알고리즘 :: 큰돌 :: Chapter 7 - DP :: 백준 9251번 LCS (최장 공통 부분 수열)

Embedded June·2023년 10월 8일
0

문제

문제 링크

해설

  • LCS는 대표적인 DP 문제로 푸는 방법이 정해져있으니 외워두는 것이 좋습니다.
  • 공집합도 부분집합의 하나이므로, 빈문자(공백)를 포함해서 DP[첫번째 문자열 길이 + 1][두번째 문자열 길이 + 1] 크기의 2차원 메모이제이션 배열을 생성합니다.
  • 빈문자는 부분집합의 일부지만, 부분수열의 일부라고는 볼 수 없으므로, 0번 행과 0번 열은 LCS길이를 0으로 초기화 합니다. (상단 왼쪽 그림 참고)
  • 첫 번째 글자를 비교합시다.(핑크색)
    • AC는 서로 다르므로, y축으로 윗칸, x축으로 왼쪽칸 중 큰 쪽을 가져갑니다.
  • 두 번째 글자를 비교합니다.(주황색)
    • CC는 같으므로 현재 값과 왼쪽 대각선값 + 1한 값 중 큰 쪽을 가져갑니다.
    • 문자열 AC와 문자열 C는 LCS가 1이므로 값이 맞는것을 확인할 수 있습니다.
  • 위 내용을 식으로 정리하면,
if (글자 다르면)
    DP[y][x] = max(DP[y][x - 1], DP[y - 1][x]);
else
    DP[y][x] = max(DP[y][x], DP[y - 1][x - 1]);
  • 이 규칙성을 유지하면서 마지막까지 진행한 뒤 우측 하단값을 출력하면 됩니다.

코드

#include <iostream>
using namespace std;

string A, B;
int lenA, lenB;
int DP[1002][1002];

int main() {
	cin.tie(0)->sync_with_stdio(0);
	cin >> A >> B;
	lenA = A.size(), lenB = B.size();
	for (int y = 1; y <= lenB; ++y)
		for (int x = 1; x <= lenA; ++x)
			DP[y][x] = (B[y - 1] == A[x - 1]) ? DP[y - 1][x - 1] + 1 : max(DP[y - 1][x], DP[y][x - 1]);
	cout << DP[lenB][lenA];
}

소스코드 링크

결과

profile
임베디드 시스템 공학자를 지망하는 컴퓨터공학+전자공학 복수전공 학부생입니다. 타인의 피드백을 수용하고 숙고하고 대응하며 자극과 반응 사이의 간격을 늘리며 스스로 반응을 컨트롤 할 수 있는 주도적인 사람이 되는 것이 저의 20대의 목표입니다.

0개의 댓글