https://www.acmicpc.net/problem/9252
안녕하세요
오늘 풀어볼 문제는 백준 9252번, 골드 4번 문제입니다.
LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제로 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 프로그램을 구한다.
조건
- 첫째 줄과 둘째 줄에 두 문자열이 주어진다. 문자열은 알파벳 대문자로만 이루어져 있으며, 최대 1000글자로 이루어져 있다.
아이디어
- DP 배열 정의:
- : A[1…i]A[1 \ldots i]와 B[1…j]B[1 \ldots j]의 LCS 길이.
- 점화식:
- 일 경우:
- dp[i][j]=dp[i−1][j−1]+1
- 일 경우
- dp[i][j]=max(dp[i−1][j],dp[i][j−1])
- 일 경우:
- 수열 복원:
- dp 배열을 역추적하여 LCS 문자열을 복원.
- 초기값:
- :
- 빈 문자열과의 LCS 길이는 항상 0
- :
코드
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int main (void){
ios_base::sync_with_stdio(false);
cin.tie(NULL);
string A, B;
cin >> A >> B;
int n = A.size();
int m = B.size();
// dp 배열 초기화
vector<vector<int>> dp(n+1, vector<int>(m+1, 0));
//dp 점화식 계산
for(int i=1; i<=n; i++){
for(int j =1; j<=m; 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]);
}
}
}
// lcs 길이 출력
cout << dp[n][m]<<"\n";
if(dp[n][m]!=0){
//lcs 복원
string lcs = "";
int i = n, j = m;
while (i > 0 && j > 0) {
if (A[i - 1] == B[j - 1]) {
lcs += A[i - 1]; // 공통 문자를 LCS에 추가
i--;
j--;
} else if (dp[i - 1][j] >= dp[i][j - 1]) {
i--; // 위쪽으로 이동
} else {
j--; // 왼쪽으로 이동
}
}
// LCS 문자열 출력 (역순이므로 뒤집기)
reverse(lcs.begin(), lcs.end());
cout << lcs << "\n";
}
return 0;
}

오늘도 끝
'algorithm > baekjoon' 카테고리의 다른 글
| [nodejs] 백준 1057번 (0) | 2025.05.09 |
|---|---|
| [C/C++] 백준 14002번 (1) | 2025.01.11 |
| [C/C++] 백준 11055번 (0) | 2025.01.10 |
| [C/C++] 백준 11053번 (0) | 2025.01.09 |
| [C/C++] 백준 1912번 (2) | 2025.01.08 |