Always awake
[백준][9252][Python 파이썬][G4] LCS 2 본문
문제
LCS(Longest Common Subsequence, 최장 공통 부분 수열)문제는 두 수열이 주어졌을 때, 모두의 부분 수열이 되는 수열 중 가장 긴 것을 찾는 문제이다.
예를 들어, ACAYKP와 CAPCAK의 LCS는 ACAK가 된다.
입력
첫째 줄과 둘째 줄에 두 문자열이 주어진다. 문자열은 알파벳 대문자로만 이루어져 있으며, 최대 1000글자로 이루어져 있다.
출력
첫째 줄에 입력으로 주어진 두 문자열의 LCS의 길이를, 둘째 줄에 LCS를 출력한다.
LCS가 여러 가지인 경우에는 아무거나 출력하고, LCS의 길이가 0인 경우에는 둘째 줄을 출력하지 않는다.
테스트케이스
ACAYKP CAPCAK |
KKKBCBCAAA KCKBCBCAKK |
AAAA AAA |
ABCDEF BEFDEFACDFABZ |
4 ACAK |
7 KKBCBCA |
3 AAA |
4 BDEF |
코드
import sys
input = sys.stdin.readline
stra = input().rstrip()
strb = input().rstrip()
alen = len(stra)
blen = len(strb)
dp = [[0 for i in range(alen)] for j in range(blen)]
if stra[0] == strb[0]:
dp[0][0] = 1
for i in range(1, alen):
if dp[0][i-1] == 1:
dp[0][i] = 1
elif strb[0] == stra[i]:
dp[0][i] = 1
for i in range(1, blen):
if dp[i-1][0] == 1:
dp[i][0] = 1
elif stra[0] == strb[i]:
dp[i][0] = 1
for i in range(1, blen):
for j in range(1, alen):
if stra[j] == strb[i]:
dp[i][j] = max(dp[i][j-1], dp[i-1][j-1]+1)
else:
dp[i][j] = max(dp[i-1][j], dp[i][j-1])
ans = dp[blen-1][alen-1]
print(ans)
x = blen-1
y = alen-1
stk = []
while(ans>0):
while(y>0):
if dp[x][y-1] <= ans-1:
break
y -= 1
while(x>0):
if dp[x-1][y] <= ans-1:
break
x -= 1
stk.append(strb[x])
x -= 1
y -= 1
ans -= 1
stk.reverse()
print(''.join(map(str, stk)))
후기
적당히 2차원 DP테이블로 만들고, 해당 숫자가 가장 처음 만들어진 타이밍을 찾아가면서 추적했다.
'PS > 백준 BOJ' 카테고리의 다른 글
[백준][2252][Python 파이썬][G3] 줄 세우기 (1) | 2023.11.28 |
---|---|
[백준][1005][Python 파이썬][G3] ACM Craft (0) | 2023.11.28 |
[백준][13335][C++][S1] 트럭 (1) | 2023.11.28 |
[백준][11049][Python 파이썬][G3] 행렬 곱셈 순서 (1) | 2023.11.28 |
[백준][10942][Python 파이썬][G4] 팰린드롬? (1) | 2023.11.28 |