반응형
1. 문제
2. 접근 방법
다이나믹 프로그래밍 문제이다.
이틀에 걸쳐 다양한 접근 방법을 생각해보았으나, 결국 내 능력의 한계로 풀지 못해서 답을 봐야만 했다.
나에게 좌절감을 안겨준 문제이자, 동시에 자극을 준 문제이기도 하다. (더 열심히 해야겠다!)
어쨌든... 접근 방법은 다음과 같다.
위와 같이, 비교 대상인 두 문자를 각각 행과 열로 가지는 배열을 생성한다.
여기에서는 각 시작 문자 앞에 '0' 을 추가하여 0번 행과 열은 모두 0의 값을 가지게 한다. (계산을 위함)
그 후, Z의 순서로 계산을 해나가면 되는데, i행 j열의 계산 방법은 다음과 같다.
(1) 행과 열의 문자가 일치할 경우
= 좌 대각선 위의 값 + 1
→ 문자가 일치하므로, 이전까지의 LCS에 1을 더하기 위함이다. 즉, 이전까지의 LCS가 좌 대각선의 값임
(2) 행과 열의 문자가 일치하지 않을 경우
= 왼쪽 값, 위의 값 중 더 큰 값을 그대로 갖는다.
→ 문자가 불일치하므로, 비교한 문자가 포함되어 있는 직전 LCS의 값을 그대로 가져온다.
이런 식으로 계산을 진행하다보면 다음과 같이 배열이 만들어진다.
여기에서 최종으로 만들어지는 숫자가 두 문자의 LCS가 된다. 여기에서는 4의 값을 가진다.
각 중에서 최초로 숫자의 변화가 이루어지는 열 중, 가장 열의 번호가 빠른 것들을
체크해나가다보면 LCS의 문자를 확인할 수 있다.
여기에서는 'ACAK' 임을 알 수 있다.
3. 코드
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
char s1[1001], s2[1001];
int dp[1001][1001];
int main(void)
{
scanf("%s %s", s1 + 1, s2 + 1);
int i, j;
for (i = 1; s1[i]; i++)
for (j = 1; s2[j]; j++)
if (s1[i] == s2[j])
{
dp[i][j] = dp[i - 1][j - 1] + 1;
}
else
{
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
}
printf("%d\n", dp[i - 1][j - 1]);
return 0;
}
반응형
'Programming > 백준 문제풀이' 카테고리의 다른 글
[백준/10816] 숫자 카드 2 (이분 탐색) (0) | 2020.08.20 |
---|---|
[백준/12865] 평범한 배낭 (KnapSack 문제) (1) | 2020.08.03 |
[백준/2579] 계단 오르기 (C++) (0) | 2020.07.26 |
[백준/11053] 가장 긴 증가하는 부분 수열 (LIS, Longest Increasing Subsequence) (0) | 2020.07.26 |
[백준/11729] 하노이 탑 이동 순서 (C++) (0) | 2020.07.18 |