[백준] 9251번: LCS [파이썬]

윤상원·2021년 10월 10일
1

알고리즘

목록 보기
1/1

https://www.acmicpc.net/problem/9251

문제


입력 및 출력


문제 풀이 review

입력으로 받은 두 문자열 전체에서 가장 길이가 긴 문자열을 바로 찾아내는 방법은 너무 까다롭다.

따라서 문제를 먼저 작은 문제로 나누어 접근해야 한다.

작은 문제로 나누는 방법은 문자열의 길이를 작게 만들면 된다.

길이가 짧은 문자열의 부분 수열은 그 문자열을 포함하는 긴 문자열의 부분 수열을 포함하고 있기 때문에 앞 단계의 연산이 뒷 단계의 연산에 사용된다.

따라서 이 문제는 다이나믹 프로그래밍 알고리즘을 사용해야한다.

다이나믹 프로그래밍 알고리즘 중에서도 bottom-up 방식의 다이나믹 프로그래밍으로 문제를 해결하기 위해서는 앞 단계의 연산을 저장해 놓을 배열과 앞 단계의 연산을 뒷 단계에 적용시킬 방법인 점화식이 필요하다.

1. 마지막 문자열이 같을 때

LCS는 다음과 같이 나타낼 수 있다.
LCS(str1,str2) = LCS(str1 [ :-1 ], str2[ :-1 ]) + 1

2. 마지막 문자열이 다를 때

LCS는 다음과 같이 나타낼 수 있다.
LCS(str1, str2) = max( LCS(str1[ :-1 ], str2), LCS(str1, str2[ :-1 ]) )

점화식

casestr1[-1] == str2[-1]str1[-1] != str2[-1]
점화식LCS(str1,str2) = LCS(str1[:-1], str2[:-1]) + 1LCS(str1,str2) = max(LCS(str1[:-1],str2), LCS(str1,str2[:-1])

파이썬 코드

1
2
3
4
5
6
7
8
9
10
str1 = '!' + input() #입력받은 문자열의 0번 인덱스를 참조할때
str2 = '@' + input() #i-1 인덱스를 참조하는 경우 Index Error를 방지하기 위해 '!','@' 집어넣음
memo = [[0]*len(str2) for i in range(len(str1))]
 
for i in range(1,len(str2)):
    for j in range(1,len(str1)):
        if str1[j] != str2[i]: memo[j][i] = max(memo[j-1][i], memo[j][i-1])
        else: memo[j][i] = memo[j-1][i-1+ 1
 
print(memo[len(str1)-1][len(str2)-1])
cs

0개의 댓글