개발세발은 안되요

[백준 9251: LCS] [C] 본문

알고리즘/백준

[백준 9251: LCS] [C]

금호박 2022. 9. 5. 16:15

문제 설명

LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다.

예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.

입력: 첫째 줄과 둘째 줄에 두 문자열이 주어진다. 문자열은 알파벳 대문자로만 이루어져 있으며, 최대 1000글자로 이루어져 있다.

출력: 첫째 줄에 입력으로 주어진 두 문자열의 LCS의 길이를 출력한다.

풀이 방법

dp 배열에 해당 index 까지의 LCS를 저장한다. 이때 이차원 배열을 이용하여 두개의 문자열이 함께 검사될 수 있도록 한다. 그리고 dp의 가장 마지막에 저장된 LCS 값을 출력한다.

(숫자를 잘못 적은 부분도 있지만, 이런 식의 구현을 하면 된다.)

어려웠던 점

dp를 이차원 배열로 만들 생각을 처음에 하지 못했다.

 

코드

#include<stdio.h>
#include<string.h>
char arr1[1001] = {};
char arr2[1001] = {};
int dp[1001][1001] = {};

int main(void) {
	scanf("%s", arr1);
	scanf("%s", arr2);
    // 각 자리까지의 최대 수열 길이 구하기
	for (int i = 1; i <= strlen(arr1); i++) {
		for (int j = 1; j <= strlen(arr2); j++) {
			if (arr1[i-1] == arr2[j-1]) {
				dp[i][j] = dp[i-1][j-1] + 1; // 같은 알파벳을 만났을 경우, 최대 길이가 1 증가
			}
			else { // 그렇지 않은 경우, 바로 전의 행과 열 중 더 길이가 긴 값을 불러온다.
				if (dp[i - 1][j] >= dp[i][j - 1]) dp[i][j] = dp[i - 1][j]; 
				else dp[i][j] = dp[i][j - 1]; 
			}
		}
	}
	printf("%d", dp[strlen(arr1)][strlen(arr2)]);
	return 0;
}