
오늘의 백준 문제는 평범한 배낭이다. DP를 활용하여 풀 수 있고 문제를 풀면서 DP테이블을 그려봐도 느낌적으로는 알겠는데, 정확히 왜 저런 점화식이 나오는지 이해가 가지 않았다.

아이패드가 없는 자의 서러움 너무 볼품이 없어 마크다운으로 DP테이블을 정리했다.
| 아이템↓\무게→ | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
|---|---|---|---|---|---|---|---|---|
| (0) 없음 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| (1) 6,13 | 0 | 0 | 0 | 0 | 0 | 0 | 13 | 13 |
| (2) 4,8 | 0 | 0 | 0 | 0 | 8 | 8 | 13 | 13 |
| (3) 3,6 | 0 | 0 | 0 | 6 | 8 | 8 | 14 | 14 |
| (4) 5,12 | 0 | 0 | 0 | 6 | 8 | 12 | 14 | 14 |
행 1: 아이템 1 (무게 6, 가치 13)을 고려한 후: 무게 6 이상에서 13이 가능
행 2: 아이템 2까지 고려하면 무게 4에서 8, 무게 6에서는 여전히 아이템 1이 더 유리하므로 그대로 유지
행 3: 아이템 3을 더해 무게 6일 때, 3번(3,6) + 2번(4,8) = 14로 갱신
행 4: 아이템 4를 더해도 최대 가치는 여전히 14
이렇게 표로 DP테이블을 그려보면 점화식이 왜 저렇게 나온지 알 수 있다.
dp = [[0] * (k+1) for _ in range(n+1)]
if j < w:
dp[i][j] = dp[i-1][j]
else:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-w] + v)
현재 물건을 넣을 수 있을 때 두 가지 선택이 있음
# 평범한 배낭 문제 (Knapsack Problem) - 동적 계획법으로 해결
import sys
input = sys.stdin.readline
def dynamic(goods):
dp = [[0] * (k+1) for _ in range(n+1)]
for i in range(1, n+1):
for j in range(1, k+1):
w = goods[i-1][0] # 현재 물건의 무게
v = goods[i-1][1] # 현재 물건의 가치
# 현재 물건의 무게가 배낭 용량보다 크면
if j < w:
dp[i][j] = dp[i-1][j]
else:
dp[i][j] = max(dp[i-1][j], dp[i-1][j-w] + v)
print(dp[n][k])
# 물건 개수, 최대 무게
n, k = map(int, input().split())
#무게, 가치
goods = [list(map(int, input().split())) for _ in range(n)]
dynamic(goods)