https://www.acmicpc.net/problem/9251
참고:
최장 공통 부분수열, LCS(Longest Common Subsequence) (파이썬)
LCS (Longest Common Subsequence)이란? 2개 이상의 문자열에서에서 공통으로 나타나는 부분 문자열 중 가장 긴 문자열을 의미합니다. LCS은 대표적으로 DNA의 공통 염기서열을 찾아 데이터를 압축하거나
osnim.tistory.com
DP를 이용
LCS의 점화식 구하기
예시1)
문자열 1: ACP
문자열 2: CAP
DP[N][M]을 구해야 합니다.
맨 뒤의 두 문자 비교(P와 P)
두 문자가 동일하면 -> +1
그 앞의 문자열을 비교(AC와 CA) -> DP[N-1][M-1]
예시2)
문자열 1: ACP
문자열 2: CAD
DP[N][M]을 구해야 합니다.
맨 뒤의 두 문자 비교(P와 D)
두 문자가 동일하지 않다면
그 앞의 문자열을 비교(ACP와 CA 비교, AC와 CAD 비교) -> DP[N-1][M] , DP[N][M-1]
더 큰 것을 고른다 -> MAX()
LCS 점화식
문자가 동일할 때: DP[N-1][M-1] + 1
문자가 동일하지 않을 때: MAX(DP[N-1][M], DP[N][M-1])
문자열 1: ACAK
문자열 2: CKP
로 다시 한 번 해보겠습니다.
문자열이 없을 때는 다 0
A와 C 비교(다름)
A와 문자열X,
C와 문자열X
비교한 것 중 최대값
C와 C 비교(같음)
이전 문자열들(A와 문자열X) 확인
(A와 문자열X 비교) + (C와 C 동일)
A와 C 비교(다름)
ACA와 문자열X,
AC와 C
비교한 것 중 최대값
...
C와 K 비교(다름)
AC와 C 비교(1)
A와 CK 비교(0)
K와 K 비교
이전 문자열 비교(ACA와 CK) + 1
코드로 만들어보겠습니다.
import sys
iMput = sys.stdin.readline
str1 = input().rstrip()
str2 = input().rstrip()
M = len(str1) # 열
N = len(str2) # 행
dp = [[0] * (M+1) for _ in range(N+1)] # 글자 수 + 빈 문자열
for n in range(1, N+1):
for m in range(1, M+1):
if str2[n-1] == str1[m-1]: # n과 m 이 1부터 시작해서 -1 해줌
dp[n][m] = dp[n-1][m-1] + 1
else:
dp[n][m] = max(dp[n-1][m], dp[n][m-1])
print(dp[n][m])
'코딩테스트 문제' 카테고리의 다른 글
[프로그래머스/Python] PCCP 기출문제 2번 / 퍼즐 게임 챌린지 (0) | 2025.02.25 |
---|---|
[백준/Python] 곱셈 (0) | 2025.02.09 |
[Python] 반복문으로 dfs 구현하기 (0) | 2025.01.14 |
[백준/Python] 동물원 (0) | 2024.10.29 |
[백준/Python] 이진 검색 트리 (1) | 2024.10.17 |