득이공간

[백준 C++] 9252 LCS 2 - 다이나믹프로그래밍 본문

PS/알고리즘 문제풀이

[백준 C++] 9252 LCS 2 - 다이나믹프로그래밍

쟁득 2024. 2. 23. 16:12
 

9252번: LCS 2

LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.

www.acmicpc.net

#include <iostream>
#include <string>
using namespace std;

int DP[1001][1001];

int main()
{
	ios::sync_with_stdio(false);
	cin.tie(NULL); cout.tie(NULL);

	string A, B;
	cin >> A >> B;

	int N = A.size();
	int M = B.size();
	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][j - 1], DP[i - 1][j]);
			}
		}
	}

	string Solution;

	int i = N;
	int j = M;
	while (i > 0 && j > 0)
	{
		if (DP[i][j] == DP[i - 1][j])
		{
			--i;
		}
		else if (DP[i][j] == DP[i][j - 1])
		{
			--j;
		}
		else
		{
			Solution.push_back(A[i - 1]);
			--i;
			--j;
		}
	}

	cout << Solution.size() << '\n';
	for (int i = Solution.size() - 1; i >= 0; --i)
	{
		cout << Solution[i];
	}
}

 

DP의 메모이제이션을 활용해서 특정 두 문자열의 LCS(최장공통부분수열) 길이를 저장해서 푸는 문제입니다.

 

풀이 방법은 점화식을 이용해서 아래의 그림처럼 2차원 배열에 특정 두 문자까지의 LCS 길이를 저장해주는 것입니다.

 

i, j를 0부터 1씩 증가시키면서 두 문자를 비교하고 값을 채워줍니다.

 

두 문자가 같으면, 왼쪽 위 대각선 값에 1을 더해준 값을 저장합니다. -> DP[i][j] = DP[i - 1][j - 1] + 1

두 문자가 다르면, 왼쪽 값과 위의 값 중 더 큰 값을 저장합니다. -> DP[i][j] = max(DP[i][j - 1], DP[i - 1][j])

 

위의 과정을 반복해서 DP 값을 모두 채우고 나면 해당 배열에 저장된 값 중 가장 큰 값이 두 문자열의 LCS 길이가 됩니다.

 

 

그다음은 위의 그림처럼 DP 배열에서 맨 오른쪽 아래 칸 부터 왼쪽 또는 위쪽으로 이동하면서

현재의 값이 왼쪽 값, 위쪽 값과 모두 다르면 현재 위치의 문자를 저장합니다. - 이때는 왼쪽 위 대각선으로 이동

값이 0이 나올 때까지 반복해서 위치를 이동한 다음, 저장된 문자를 역순으로 나열하면 LCS가 됩니다.

 


참고자료

 

[백준] 9251번 C/C++ 풀이 _ LCS - Easy is Perfect

출처 : https://www.acmicpc.net/problem/9251  시간 제한메모리 제한제출정답맞은 사람정답 비율1 초128 MB76453240240041.746% 문제LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때,

melonicedlatte.com

 

[DP] 9252번 LCS2

9252_LCS2 9252번 LCS 2 https://www.acmicpc.net/problem/9252 문제 LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다.

hibee.tistory.com