문제
https://www.acmicpc.net/problem/9251
9251번: LCS
LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다. 예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.
www.acmicpc.net
문제 요약
LCS(Longest Common, Subsequence, 최장 공통 부분 수열) 문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다.
주어진 두 문자열의 LCS길이를 출력한다.
예) ACAYKP 와 CAPCAK의 LCS는 ACAK가 된다.
코드
A = input()
B = input()
dp=[[0] * 1001 for _ in range(1001)]
# dp[i][j]는 인덱스 i번째까지의 A 문자열과 인덱스 j번째까지의 B 문자열 사이의 가장 긴 공통 부분 수열의 길이
# 한 쪽 문자열이 비었을 때 LCS값은 0이기 때문에 dp[i][0]와 dp[0][j]는 항상 0
ans = 0
# 최대 LCS 길이를 저장할 변수
for i in range(1, len(A) + 1):
for j in range(1, len(B) + 1):
if A[i - 1] == B[j - 1]:
# i 이하 문자열의 문자들 중 같은 문자가 있다면
dp[i][j] = dp[i - 1][j - 1] + 1
# 이전까지의 공통 부분 수열에 한 개 추가한 길이로 갱신
else:
dp[i][j] = max(dp[i - 1][j],dp[i][j - 1])
# 현재 접근한 인덱스의 문자가 LCS의 일부가 아니므로 이전 인덱스까지의 LCS길이 중 큰 값으로 설정
ans = max(ans, dp[i][j])
# 현재 접근한 인덱스의 LCS길이와 ans길이를 비교하여 더 큰 값을 저장
print(ans)
코드 설명
Bottom-Up 풀이를 사용한다.
1. 메모이제이션 테이블 dp[i][j]는 문자열 A의 i번째 인덱스까지와 문자열 B의 j번째 인덱스까지 두 문자열의 LCS 길이를 저장한다.
(초기값은 길이의 최소 값인 0이다.)
2. 이중 반복문을 이용하여 문자열 A와 B의 모든 쌍에 접근한다.
2-1. A의 i-1번째 문자와 B의 j-1번째 문자가 같다면 그 문자를 이전까지의 LCS에 추가한 길이를 dp에 저장한다.
2-1. 다르다면, 이전 까지의 수열 의 LCS 길이 중 큰 값으로 갱신한다.
3. 항상 위 과정이 끝나면 출력할 변수 ans의 길이보다 큰지 (지금까지 검사한 길이보다 큰지) 확인하고 값을 갱신한다.
'Algorithm Problems > 다이나믹 프로그래밍' 카테고리의 다른 글
[백준/Python] 11055번: 가장 큰 증가하는 부분 수열 (2) | 2023.09.06 |
---|---|
[백준/Python] 21317번: 징검다리 건너기 (2) | 2023.09.01 |
[백준/python] 14002번: 가장 긴 증가하는 부분 수열 4 (2) | 2023.08.12 |
[백준/python] 9465번: 스티커 (2) | 2023.08.11 |
[백준/python] 1463번: 1로 만들기 (2) | 2023.08.11 |