백준 - LCS 2(9252) 본문
https://www.acmicpc.net/problem/9252
9252번: LCS 2
LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.
www.acmicpc.net
LCS문제이다.
기존 알고리즘대로 푼다.
행렬 DP를 만들어준다.
ACAYKP
CAPCAK
A C A Y K P
0 0 0 0 0 0 0
C 0 0 1 1 1 1 1
A 0 1 1 2 2 2 2
P 0 1 1 2 2 2 3
C 0 1 2 2 2 2 3
A 0 1 2 3 3 3 3
K 0 1 2 3 3 4 4
이런 행렬표를 얻게 되고
LCS값은 4이다.
행렬표 끝에서 역추적을 시작해서
dp[y][x] == dp[y][x-1] 라면 왼쪽이동
dp[y][x] == dp[y-1][x] 라면 위로 이동
dp[y][x] != dp[y-1][x-1] 이라면 그때 정답리스트에 넣어준다.
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
int main() {
string str_1;
string str_2;
cin >> str_1;
cin >> str_2;
int str_1_size = str_1.size();
int str_2_size = str_2.size();
vector<vector<int>> dp(str_2_size + 1, vector<int>(str_1_size + 1, 0));
for (int i = 1; i <= str_2_size; i++) {
for (int j = 1; j <= str_1_size; j++) {
if (str_2[i - 1] == str_1[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
}
else {
dp[i][j] = max(dp[i][j - 1], dp[i - 1][j]);
}
}
}
cout << dp[str_2_size][str_1_size] << endl;;
vector<char> answer;
int y = str_2_size;
int x = str_1_size;
int count = dp[str_2_size][str_1_size];
while (dp[y][x]) {
if (dp[y][x] == dp[y][x - 1])
x -= 1;
else if (dp[y][x] == dp[y - 1][x])
y -= 1;
else {
answer.push_back(str_2[y-1]);
y -= 1;
x -= 1;
}
}
for (int i = answer.size()-1; i >= 0; i--)
cout << answer[i];
return 0;
}
'개발 > 알고리즘' 카테고리의 다른 글
백준 - 파일 합치기(11066) (0) | 2024.03.12 |
---|---|
백준 - 내리막 길(1520) (0) | 2024.03.08 |
LeetCode - Number of Subarrays That Match a Pattern II (0) | 2024.02.15 |
백준 - 외판원 순회(2098) (0) | 2024.02.11 |
백준 - 소수의 연속합(1644) (1) | 2024.02.09 |
Comments