https://www.acmicpc.net/problem/12865
다이나믹 프로그래밍을 풀 때는 표를 그리는 경우가 많았다.
표를 그린다는 것 = 컴퓨터로 생각하면 Memoization이기 때문인 것 같다.
표를 그려보고, 그 표를 컴퓨터가 만들어낼 수 있도록 일반화하는 것이 중요하다.
하지만 정답을 해결할 수 있는 표를 만들어 낼 수 있다면 이미 그 문제를 풀 수 있다는 뜻이겠지...
그러니까 어떤 경우를 순회하면서 무엇을 저장해야 하는가? 메모이제이션 아이디어를 생각하는 게 쟁점이다.
이 문제도 마찬가지이다.
지금까지 for문을 돌렸기 때문에 무작정 for문으로 시작하려 한다면 애먹을 가능성이 높다. (내가 그랬다.)
for문으로 해결하면 안 된다는 뜻이 아니라,
먼저 '표'와 같은 해결 방법을 찾아야 한다는 뜻이다.
소스코드는 아래와 같지만,
아이디어를 이해한다면 사실 소스코드는 직접 만들 수 있을 것이고
나중에 경계값 처리 등을 실수했을 때나 보면 된다.
import sys
N, K = map(int, sys.stdin.readline().split()) # N은 물건 갯수, K는 최대 무게
item = [] # 입력으로 주어질 아이템 무게/가치 리스트
for i in range(N):
item.append(list(map(int, sys.stdin.readline().split())))
W, V = 0, 1 # item 리스트에서 무게를 0, 가치를 1로 가리키면 헷갈리므로 그냥 이렇게 쓸 것이다
knapsack = [[0 for _ in range(K+1)] for _ in range(N)] # 최대 가치를 저장한 표. 문제 해결의 열쇠
for index, wv in enumerate(item):
for weight in range(1, K+1):
if wv[W] > weight:
knapsack[index][weight] = knapsack[index-1][weight]
else:
knapsack[index][weight] = max(knapsack[index-1][weight], wv[V] + knapsack[index-1][weight-wv[W]])
print(max(map(max, knapsack)))
를 참고했다. 표를 그리면서 설명을 잘 해놓으신 것 같다.
'알고리즘 > 동적프로그래밍' 카테고리의 다른 글
(프로그래머스) N으로 표현 (0) | 2020.05.02 |
---|---|
14501번. 퇴사 (DP) (0) | 2020.04.17 |
1912번. 연속합 (0) | 2019.12.06 |
2565번. 전깃줄 (0) | 2019.12.05 |
11054번. 가장 긴 바이토닉 부분 수열 (0) | 2019.12.05 |