문제 & 링크
https://www.acmicpc.net/problem/9252
풀이
1. dp 테이블을 0으로 초기화한다.
2. 두 문자열을 dp 테이블의 1부터 시작하도록 반복문을 설정한다.
3. 각 문자열의 원소가 같을 경우 dp[i][j]라면 dp[i-1][j-1]에서 1을 더해서 저장한다. 대각선의 값에서 1을 더하는 이유는 각 문자열에서 i번째 j번째 문자가 빠졌을 때 i-1번째, j-1번째 까지의 공통 부분 수열이 1 줄어야 하기 때문이다.
4. 각 문자열의 원소가 다를 경우 dp[i][j]라면 dp[i-1][j]와 dp[i][j-1] 중 큰 값을 저장한다.
5. 3 - 4의 과정을 반복하며 dp 테이블의 마지막 원소에서 LCS의 길이를 구할 수 있다.
6. dp 테이블의 마지막 원소(LCS의 길이)로부터 역으로 추적하여 LCS의 길이가 0이 될 때 까지의 경로를 구한다.
7. 만약 현재 위치인 dp[i][j]와 dp[i-1][j-1]이 같은 값이라면 dp[i-1][j-1]로 이동한다.
8. 만약 7의 조건을 만족하지 않지만 dp[i-1][j] 또는 dp[i][j-1]와 같은 값이라면 해당 위치로 이동한다.
9. 7과 8의 조건을 모두 만족하지 않는다면 dp[i-1][j-1]로 이동하며 해당 문자열의 인덱스에 해당하는 문자를 저장한다.
10. 7 - 9의 과정을 반복하며 dp 테이블의 원소가 0이 될 경우 LCS를 구할 수 있다.
참고 자료
코드
#include <iostream>
#include <string>
using namespace std;
int dp[1001][1001] = {0};
int main() {
string S1, S2;
string ans = "";
cin >> S1;
cin >> S2;
for (int i = 1; i <= S1.length(); i++) {
for (int j = 1; j <= S2.length(); j++) {
if (S1[i - 1] == S2[j - 1]) dp[i][j] = dp[i - 1][j - 1] + 1;
else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
}
int i = S1.length(), j = S2.length();
while (dp[i][j] != 0) {
if (dp[i - 1][j - 1] == dp[i][j]) {
i--;
j--;
}
else if (dp[i - 1][j] == dp[i][j]) i--;
else if (dp[i][j - 1] == dp[i][j]) j--;
else {
ans = S1[i - 1] + ans;
i--;
j--;
}
}
cout << dp[S1.length()][S2.length()] << "\n";
if (dp[S1.length()][S2.length()] != 0) cout << ans;
}
'Koala - 15기 > 코딩테스트 준비 스터디' 카테고리의 다른 글
[백준/c++] 1417번 : 국회의원 선거 (0) | 2024.08.04 |
---|---|
[백준/Python] 2164번: 카드2 (0) | 2024.08.04 |
[백준/C++] 1107번: 리모컨 (0) | 2024.08.04 |
[백준/python] 10773 : 제로 (0) | 2024.08.04 |
[백준/C++] 1012번 : 유기농 배추 (0) | 2024.08.04 |