공부 자료/알고리즘

(Python/파이썬) 백준 12865번 - 평범한 배낭

뚜루뚜루세니 2021. 8. 13. 11:18
728x90

문제출처: https://www.acmicpc.net/problem/12865

 

12865번: 평범한 배낭

첫 줄에 물품의 수 N(1 ≤ N ≤ 100)과 준서가 버틸 수 있는 무게 K(1 ≤ K ≤ 100,000)가 주어진다. 두 번째 줄부터 N개의 줄에 거쳐 각 물건의 무게 W(1 ≤ W ≤ 100,000)와 해당 물건의 가치 V(0 ≤ V ≤ 1,000)

www.acmicpc.net

1. 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
n, k = map(int, input().split())
 
item = [[0,0]]
= [[0]*(k+1for _ in range(n+1)]
 
for i in range(n):
    item.append(list(map(int, input().split())))
 
for i in range(1, n+1):
    for j in range(1, k+1):
        w = item[i][0]
        v = item[i][1]
 
        if j < w:
            d[i][j] = d[i-1][j]
        else:
            d[i][j] = max(d[i-1][j], d[i-1][j-w]+v)
 
print(d[n][k])
cs

 

2. 해결과정

냅색(knapsack)알고리즘 이라고 불리는 문제이다.

배낭의 용량이 정해져 있을 때 , 최대한의 가치를 가질 수 있도록 배낭을 싸야하는 문제이다.

냅색 알고리즘은 담을 수 있는 물건이 나눌 수 있는지 여부에 따라 달라지게 된다.

담을 수 있는 물건이 나눠지면(ex. 설탕 몇 g, 소금 몇 g)  분할 가능한 배낭 문제가 되고

담을 수 있는 물건이 나눠지지 않는다면 0-1 배낭 문제가 된다.

 

위 문제는 0-1 배낭 문제이다.

 

알고리즘을 설명해주면, x축에는 우선 k까지의 가방의 무게, y축에는 물건 n개 개수 만큼의 배열을 만들어준다.

행을 차례대로 돌면서

1) 현재 배낭의 허용 무게보다 넣을 물건의 무게가 더 크면 넣지 않음  --> j<weight : d[i][j]=d[i-1][j]

2) 그렇지 않으면 더 큰 가치 선택

   - 현재 넣을 물건의 무게만큼 배낭에서 뺌. 현재 물건 넣음 --> 그 무게의 배낭이 가지는 최대 가치가 이미 저장됨

   - 현재 물건 넣지 않고 이전 배낭 그대로

--> d[i][j] = max( d[i-1][ j-weight ]+value ), d[i-1][j] )

 

3. 느낀점

진심 엄청 어려웠다. 그래서 다른 사람들이 어떻게 풀었는지도 엄청 찾아봤다. dp의 기본 문제 중 하나라고 하는데 기본도 못푸는 것 같아서 약간 매우 현타가 왔다. 그래도 한발 한발 천천히 노력하다보면 이런 문제도 풀 수 있지 않을까,,? ㅜㅜㅜ

728x90