Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |
Tags
- 클래스
- 피보나치 수
- 백트래킹
- 재귀
- 우선순위 큐
- 시뮬레이션
- 순열
- MST
- 링크드리스트
- 큐
- 문자열
- 스택
- lis
- 이분 탐색
- 빠른 입출력
- 그리디
- BeautifulSoup
- 비트마스크
- DP
- 분할 정복
- 세그먼트 트리
- 조합
- BFS
- 메모리풀
- 중복 순열
- 완전 탐색
- SSAFY
- dfs
- 크루스칼
- Knapsack
Archives
- Today
- Total
작심 24/7
[백준] 9252번 LCS 2 본문
9252번: LCS 2
LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.
www.acmicpc.net
LCS(Longest Common Subsequence) 문제이다.
LCS(Longest Common Substring)과 같이
문자열 A, B에서
A[i]와 B[j]가 같을 때는
DP[i][j] = DP[i-1][j-1] + 1
이 되지만
A[i]와 B[j]가 다를 때는
DP[i][j] = max(DP[i-1][j], DP[i][j-1]) + 1
이 된다.
그러면 최종적으로
DP[문자열A 끝][문자열B 끝]이
LCS의 길이가 된다.
LCS를 출력하는 과정은
함수를 만들어 재귀 호출로
DP[문자열A 끝][문자열B 끝]부터 역으로
현재 값이 어디에서 왔는지를 추적해주어야 한다.
DP[i][j]에서 A[i]와 B[j]가 같을 땐
이 문자가 LCS에 포함되므로 결과에 추가해주고
대각선 위에서 왔으므로
i-1, j-1를 추적하러 간다.
A[i]와 B[j]가 다를 땐
왼쪽(i, j-1) 이나 위(i-1, j) 에서 왔으므로
이 중에서 더 큰 값을 가진 곳으로 추적하러 간다.
i나 j가 범위를 벗어나면 빠져나온다.
결과에 있는 문자열은 역추적 되어있는 상태이므로
그것을 뒤집은 뒤 출력해줘야 한다.
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
string a, b, res;
int dp[1002][1002];
void LCS(int x, int y) {
if (x == 0 || y == 0) return;
if (a[x - 1] == b[y - 1]) {
res += a[x - 1];
LCS(x - 1, y - 1);
}
else {
if (dp[x - 1][y] > dp[x][y - 1]) LCS(x - 1, y);
else LCS(x, y - 1);
}
}
int main() {
cin >> a >> b;
for (int i = 0; i < a.size(); i++) {
for (int j = 0; j < b.size(); j++) {
if (a[i] == b[j]) dp[i + 1][j + 1] = dp[i][j] + 1; // 같으면 대각선 위 값 + 1
else dp[i + 1][j + 1] = max(dp[i + 1][j], dp[i][j + 1]); // 다르면 왼쪽이나 위에서 더 큰 값을 가져옴
}
}
LCS(a.size(), b.size());
reverse(res.begin(), res.end());
cout << dp[a.size()][b.size()] << endl;
if (res.size()) cout << res << endl;
return 0;
}
'백준' 카테고리의 다른 글
[백준] 16500번 문자열 판별 (0) | 2020.08.27 |
---|---|
[백준] 11652번 카드 (0) | 2020.08.27 |
[백준] 5582번 공통 부분 문자열 (0) | 2020.08.25 |
[백준] 7579번 앱 (0) | 2020.08.25 |
[백준] 14003번 가장 긴 증가하는 부분 수열 5 (0) | 2020.08.20 |
Comments