백준 12865번 python 풀이 - 평범한 배낭
문제 링크
해결책
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import sys
N, K = map(int, sys.stdin.readline().split())
things = []
for _ in range(N):
weight, value = map(int, sys.stdin.readline().split())
things.append((weight, value))
things.sort(key=lambda x: x[0])
dp = [[0 for i in range(K+1)] for j in range(N+1)]
for i in range(1, N+1):
weight, val = things[i-1]
for j in range(1, K+1):
if(j < weight):
dp[i][j] = dp[i - 1][j]
else:
dp[i][j] = max(dp[i-1][j-weight] + val, dp[i-1][j])
# i 가 물건(열), j가 무게(행)
print(dp[-1][-1])
주석으로 달 설명
KNAPSACK 문제이다.
DP문제에서 주된 생각의 흐름은 다음과 같다.
- 이 문제, 반복적이다 or Divide 가 가능하다
- 이로 인해 진행될 때, 반복적인 흐름이 보인다.
이를 기반으로 문제의 크기를 분할하여 감소시켜야 하는데, 이 때 올바른 방식의 분할을 진행하여야 한다.
KNAPSACP 문제의 경우에는, 분할할 때 ABCDE의 물건이 있고, 최대 무게가 K 라고 하면, E가 포함되는 경우와 포함되지 않는 경우로 분할한다. 그렇게 되면, ABCD와 K-(A무게) 그리고 ABCD와 K 로 분할된다. 이때, K-(무게) 가 0 미만이 되는 경우는 없다.
이와 같이 분할한 뒤, 2차원배열을 사용하면 된다.
This post is licensed under CC BY 4.0 by the author.