LCS
10 August 2019
문제 : https://www.acmicpc.net/problem/9251
이번은 LCS(Longest Common Subsequence)를 구하는 문제를 풀어보도록 하겠습니다.
#include<stdio.h>
#include<string.h>
#define max(a,b) (((a)>(b))?(a):(b))
static char* first;
static char* second;
static int** lcs_arr;
void init();
int lcs(int i, int k);
int main(void) {
init();
printf("%d\n", lcs(strlen(first) - 1, strlen(second) - 1));
return 0;
}
void init() {
first = new char[1000];
second = new char[1000];
scanf("%s", first);
scanf("%s", second);
lcs_arr = new int*[strlen(first)];
for (int i = 0; i < strlen(first); i++)
{
lcs_arr[i] = new int[strlen(second)];
for (int k = 0; k < strlen(second); k++)
{
lcs_arr[i][k] = -1;
}
}
}
int lcs(int i, int k) {
if (i == -1 || k == -1)
{
return 0;
}
if (lcs_arr[i][k] == -1)
{
if (first[i] == second[k])
{
lcs_arr[i][k] = lcs(i - 1, k - 1) + 1;
}
else {
lcs_arr[i][k] = max(lcs(i - 1, k), lcs(i, k - 1));
}
}
return lcs_arr[i][k];
}
두 수열이 주어졌을 때, 각각의 수열을 a(i), b(k)라고 생각하고, 두 수열에서 해당 길이까지 가장 긴 부분 수열의 길이를 lcs(a(i), b(k))라고 정의해봅시다.만약 마지막 문자의 값이 똑같다면 lcs(a(i), b(k)) = lcs(a(i-1), b(k-1)) + 1 과 같습니다.
만약 마지막 문자의 값이 다르다면 lcs(a(i), b(k)) = MAX(lcs(a(i), b(k-1),lcs(a(i-1), b(k)) 로 정의할 수 있습니다.
예를 들면, 각각의 수열을 아래로 정의합니다.
ACAYKP
CAPCAK
마지막 문자가 다르므로 최대 길이는 MAX(lcs(ACAYKP,CAPCA), lcs(ACAYK,CAPCAK))와 같고,
lcs(ACAYK,CAPCAK)에서는 마지막 문자가 같으므로, lcs(ACAYK,CAPCAK) = lcs(ACAY,CAPCA) + 1 과 같습니다.
메모이제이션을 이용해 각각의 값을 arr에 저장해주고, 함수를 만들어 return 하도록 합니다.