문제 정의
두 문자열(수열) \(A, B\)가 주어질 때, 둘 모두의 부분 수열(순서 유지, 연속일
필요 없음)이 되는 가장 긴 수열의 길이를 구합니다. 예: ACAYKP 와 CAPCAK
의 LCS는 ACAK (길이 4).
상태 정의
$$ dp[i][j] = A[1..i],\ B[1..j]\text{의 LCS 길이} $$
점화식
마지막 문자를 비교하면 두 경우뿐입니다.
$$ dp[i][j] = \begin{cases} dp[i-1][j-1] + 1 & A_i = B_j \\ \max(dp[i-1][j],\ dp[i][j-1]) & A_i \ne B_j \end{cases} $$
- 마지막 문자가 같으면 — 그 문자를 LCS에 포함시키는 것이 항상 손해가 아님을
교환 논법으로 보일 수 있습니다. - 다르면 — 둘 중 하나는 LCS에 못 들어가므로, 한쪽을 한 글자 줄인 두 경우의
최댓값.
복잡도
상태 \(O(NM)\)개, 전이 \(O(1)\) → 시간·공간 \(O(NM)\). 길이만 필요하면 직전 행만
들고 있으면 되므로 공간을 \(O(M)\)으로 줄일 수 있습니다.
LIS와의 관계
- LCS는 두 수열의 공통 구조, LIS는 한 수열의 증가 구조.
- \(A\)와 "\(A\)를 정렬한 것"의 LCS = \(A\)의 LIS — 두 문제가 서로 환원됩니다.
- 두 수열 중 하나에 중복 원소가 없으면, LCS를 LIS로 바꿔 \(O(N \log N)\)에
풀 수도 있습니다 (위치 치환 트릭).
전형적인 변형
| 변형 | 아이디어 |
|---|---|
| LCS 문자열 복원 | dp 테이블을 거꾸로 추적 |
| 편집 거리 (edit distance) | 같은 모양의 2차원 DP, 연산 비용만 다름 |
| 공통 부분 문자열 (연속) | 다르면 0으로 리셋 — 점화식 한 줄 차이 |
| 세 수열의 LCS | 3차원 dp[i][j][k] |