728x90
반응형
9251번: LCS
문제
https://www.acmicpc.net/problem/9251
9251번: LCS
LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.
www.acmicpc.net
풀이
입력된 두 문자열을 비교하면서 LCS(최장 공통 부분 수열)의 길이를 찾는 문제. 가능한 모든 경우의 수를 확인하면 시간초과가 나기 때문에 dp를 이용해 풀어야 한다.
예제를 통해 설명을 해보자. 비교하는 두 문자열은 "ACAYKP"와 "CAPCAK"다. 최장 공통 부분 수열은 "ACAK"로 길이는 4다.
0 | A | C | A | Y | K | P | |
0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
C | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
A | 0 | ||||||
P | 0 | ||||||
C | 0 | ||||||
A | 0 | ||||||
K | 0 |
각 칸의 숫자의 의미는 LCS의 길이다. 각 행의 문자를 열을 옮기며 문자가 같은지 비교한다. 만약 문자가 같다면, 왼쪽 대각선 위의 숫자에 1을 더해 길이를 늘여준다. 문자가 다른 경우에는 왼쪽과 위쪽 수를 비교해 더 큰 값을 해당 칸에 가져간다. 위 과정을 거치면 아래 표가 된다.
0 | A | C | A | Y | K | P | |
0 | 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의 길이가 된다.
코드
#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
string a, b;
cin >> a >> b;
int a_size = a.size();
int b_size = b.size();
vector<vector<int>> dp(a_size + 1, vector<int>(b_size + 1, 0));
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];
return 0;
}
728x90
반응형
'Problem Solving > BOJ' 카테고리의 다른 글
[백준 / BOJ] C++ 1958 LCS 3 (0) | 2023.02.15 |
---|---|
[백준 / BOJ] C++ 9252 LCS 2 (0) | 2023.02.15 |
[백준 / BOJ] C++ 1269 대칭 차집합 (0) | 2023.02.14 |
[백준 / BOJ] C++ 1267 핸드폰 요금 (0) | 2023.02.14 |
[백준 / BOJ] C++ 14622 소수 게임 (0) | 2023.02.14 |