문제
두 문자열이 주어졌을 때, 최장 공통 부분 수열(Longest Common Subsequence)의 길이를 구하는 문제다.
핵심 아이디어
dp[i][j]= 문자열 A의 i번째까지, B의 j번째까지 고려했을 때 LCS 길이.A[i] == B[j]이면dp[i][j] = dp[i-1][j-1] + 1(공통 문자 발견).- 다르면
dp[i][j] = max(dp[i-1][j], dp[i][j-1])(한쪽을 줄여본다).
풀이
#include <iostream>
#include <string>
using namespace std;
int main() {
int dp[1001][1001];
string a, b;
cin >> a >> b;
for (int i = 1; i <= a.size(); i++) {
for (int j = 1; j <= b.size(); j++) {
if (a[i - 1] == b[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
cout << dp[a.size()][b.size()] << endl;
return 0;
}
주요 포인트
- 인덱스가 1부터 시작하므로
a[i-1],b[j-1]로 접근해야 한다. - LCS 길이뿐 아니라 실제 문자열을 복원하려면 역추적(backtracking)이 필요하다.
복잡도
- 시간: O(N × M) — N, M은 각 문자열의 길이
- 공간: O(N × M)
LCS는 diff 도구, DNA 서열 비교 등 실무에서도 활용되는 대표적인 DP 문제다.
댓글