본문 바로가기
  • 초부득3 - 어제보다 나은 내일을 위해
  • 꿈이 현실이 되는 날까지
sw사관학교 정글 2기/04 DP, 그리디

[DP] 백준 평범한 배낭 12865번 with Python3 ★

by 금의야행 2021. 8. 27.

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

 

문제

정답 풀이

import sys

N, K = map(int, input().split())
stuff = [[0,0]]


for _ in range(N):
    stuff.append(list(map(int, input().split())))


#냅색 문제 풀이
knapsack = [[0 for _ in range(K + 1)] for _ in range(N + 1)]
#냅색에는 물건 가치가 원소로 저장된다. 

#i 물건 번호 / j 담을 수 있는 무게
for i in range(1, N + 1):
    for j in range(1, K + 1):

        #현재 i 번째 물건의 무게와 값
        weight = stuff[i][0] 
        value = stuff[i][1]

        #weight보다 현재 무게가 작으면(이 물건을 담을 수 없으면) 위의 값을 그대로 가져온다| 위의값= i-1 
        if j < weight:
            knapsack[i][j] = knapsack[i - 1][j] 

        #현재 물건 i를 담을 수 있으면. 
        else:
            knapsack[i][j] = max(value + knapsack[i - 1][j - weight], knapsack[i - 1][j])
        #value + knapsack[i - 1][j - weight] 
        # = 현재 물건의 값(value) 와 남은 무게(j-weight)에 저장된 최대 가치를 더한 값을 저장
        
        #knapsack[i - 1][j] 
        # 위의 경우(지금 물건 i를 담았을때)보다 
        # 이전 물건(i-1 혹은 그 이전 물건들)을 담았던 값이 더 클 경우도 있으니 비교.

print(knapsack[N][K])

출처:https://claude-u.tistory.com/208

 

해석

유명한 알고리즘인 냅색 알고리즘을 활용한 문제이다.

 

여러 경우를 고려해봤는데 아예 최대 무게를 제외한 이전단계부터 하나하나 계산하며 올라가는 식의 동적 프로그래밍은 떠오르지 않았다. 정말 DP는 너무 아이디어를 떠올리기 힘들다.

댓글