일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 3줄정리
- 링피트
- 쓰릴오브파이트
- 읽기
- 스탭퍼
- 리얼 클래스
- 화상영어
- 미드시청
- 매일
- English
- 만화도
- leetcode
- 잡생각
- Problem Solving
- Daily Challenge
- 괜찮음
- 운동
- 사이드
- 프로젝트
- 영어원서읽기
- 파비최
- FIT XR
- realclass
- 월간
- 영어공부
- Writing
- 뭐든
- 30분
- 개발자
- 10분
Archives
- Today
- Total
파비의 매일매일 공부기록
5.6 최장 공통 부분 수열 출력하기 본문
이번 절은 지난 절에서 구한 최장 공통부분 수열 개수 구하기의 확장판이다.
(https://www.acmicpc.net/problem/9252)
지난 절에서는 개수만 구했지만, 이번에는 어떤 문자인지도 출력하는 문제다.
캐시를 만들어 나가면서 최장 공통부분 수열을 구하면 되는 걸로 생각했는데,
그게 아니라 일단 캐시를 다 만들고 끝에서부터 다시 역으로 찾아 들어가는(백 트레킹) 방식을 사용한다.
결국은 DP로 캐시를 못 만들면 아무것도 못함.. ㅠㅠ
로직은 다음과 같다.
1. (m, n)에서 시작하되, i와 j가 동일하면 LCS에 포함 후 i-1, j-1로 이동.
2. i와 j가 다르면 ar[i]와 ar[j] 중 큰 값으로 이동.
3. 0, 0까지 도달할 때까지 반복
위의 로직을 코드로 옮기면 다음과 같다.
def solve(a, b):
m, n = len(a), len(b)
cache = [[0 for __ in range(m + 1)] for _ in range(n + 1)]
for i in range(1, n + 1):
for j in range(1, m + 1):
if a[j - 1] == b[i - 1]:
cache[i][j] = cache[i - 1][j - 1] + 1
else:
cache[i][j] = max(cache[i - 1][j], cache[i][j - 1])
res = ''
j, i = m, n
while i > 0 and j > 0:
if a[j - 1] == b[i - 1]:
res += a[j - 1]
i -= 1
j -= 1
elif cache[i - 1][j] > cache[i][j - 1]:
i -= 1
else:
j -= 1
print(cache[n][m])
print(res[::-1])
return True
if __name__ == '__main__':
a = input()
b = input()
solve(a, b)
BOJ에 제출해서 PASS 됨.
백트래킹이라고 하면 되게 막연했었는데
이번 기회를 통해서 좀 익숙해진 듯하다.
일단 DP로 캐시 배 열등을 구한 다음에
끝에서부터 다시 더듬어가면서 찾는 형식으로 가면 될 듯.
그리고 딱 캐시만 쓰는 건 아니고 처음에 받았던 데이터(문자열)도 사용하는 걸 알게 됨.
반응형
'Study > Algorithm 문제풀이' 카테고리의 다른 글
5.7 거스름돈 최적화 - DP (0) | 2021.09.17 |
---|---|
5.7 거스름돈 최적화 - 재귀 (0) | 2021.09.16 |
5.5 최장 공통 부분 수열 길이 구하기 - DP (0) | 2021.09.14 |
5.5 최장 공통 부분 수열 길이 구하기 - 메모전략 (0) | 2021.09.13 |
5.5 최장 공통 부분 수열 길이 구하기 - 재귀 (0) | 2021.09.12 |
Comments