본문 바로가기
백준 문제 풀이

[백준 9252] LCS 2

by $# 2020. 3. 30.

https://www.acmicpc.net/problem/9252


해설

LCS DP 문제이며, 또 그 이후에 역추적을 사용 해 어떤 문자가 공통 문자열인지 구하는 문제입니다.

 

  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

 

공통 문자 수 구하는 건 (https://far-simple.tistory.com/37) 여기서 했으니, 저는 역추적을 설명해보겠습니다.

일단, 😊 이거 적힌 순서대로 for문을 검색해주면 됩니다. 

 

가장 오른쪽 가장 아래에서 부터 시작해서 왼쪽으로 이동합니다.

왼쪽으로 이동하면서 자기보다 왼쪽에 있는 게 자기 숫자랑 다르면 대각선 위로 올라갑니다.

만약, 자기 위에 있는 게 자기랑 숫자가 같으면 그냥 위로 올라갑니다.

올라간 게 0이 될 때 break로 빠져나오면 됩니다.

 

 

˙˙˙

 

소스코드

 

#include <iostream>
#include <algorithm>
#include <string>
using namespace std;
int dp[1001][1001];
int main() {
	string a, b; cin >> a >> b;
	for(int i=1; i<=b.size(); i++)
		for (int j = 1; j <= a.size(); j++) {
			if (a[j - 1] == b[i - 1])
				dp[i][j] = dp[i - 1][j - 1] + 1;
			else
				dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
		}
	int k = a.size();
	string kk;
    
	for (int i = b.size(); i >= 0; i--) {
		if (dp[i][k] == 0)
			break;
		for (int j = k; j >= 0; j--) {
			if (dp[i][j] == dp[i - 1][j])
				break;
			if (dp[i][j] != dp[i][j - 1]) {
				kk += a[j-1];
				k = j - 1;
				break;
			}
		}
	}
	cout << dp[b.size()][a.size()] << '\n';;
	if (dp[b.size()][a.size()] == 0)
		return 0;
	for (int i = kk.size() - 1; i >= 0; i--)
		cout << kk[i];
	cout << '\n';
}

'백준 문제 풀이' 카테고리의 다른 글

[백준 11053] 가장 긴 증가하는 부분 수열  (0) 2020.03.30
[백준 12865] 평범한 배낭  (0) 2020.03.30
[백준 9251] LCS  (0) 2020.03.28
[백준 2294] 동전 2  (0) 2020.03.27
[백준 1541] 잃어버린 괄호  (0) 2020.03.26

댓글