Algorithm/📊 Problem Solving

[백준/BOJ] 12920 - 평범한 배낭 2

posted by sangmin

12920 - 평범한 배낭 2

📌 문제

이 문제는 아주 평범한 배낭에 관한 두 번째 문제이다.

민호는 BOJ 캠프에 가기 위해 가방을 싸려고 한다. 가방에 어떠한 물건들을 넣냐에 따라 민호의 만족도가 달라진다. 집에 있는 모든 물건들을 넣으면 민호가 느낄 수 있는 만족도는 최대가 될 것이다. 하지만 민호가 들 수 있는 가방의 무게는 정해져 있어 이를 초과해 물건을 넣을수가 없다.

민호가 만족도를 최대로 느낄 수 있는 경우를 찾아보자.

단, 집에 동일한 물건들이 여러개가 있을 수 있기 때문에 한 물건을 두 개 이상 챙기는 것도 가능하다.

📋 코드

N, M = map(int, input().split())

dp = [0 for _ in range(M+1)]
weight, satisfaction = [], []
for _ in range(N):
    V, C, K = map(int, input().split())

    idx = 1
    while K > 0:
        tmp = min(idx, K)

        weight.append(V * tmp)
        satisfaction.append(C * tmp)

        idx *= 2
        K -= tmp

for i in range(len(weight)):
    for j in range(M, 0, -1):
        if j >= weight[i]:
            dp[j] = max(dp[j], dp[j-weight[i]] + satisfaction[i])

print(dp[M])

💡 한마디

시간 초과 때문에 굉장히 애먹었고, 왜 플래티넘인지 몸소 느낀 문제였다.

  • 첫번째 풀이 : K개 물건 전부 입력받아 2차원 DP 테이블을 만들고, 배낭정리 풀이 -> 시간 초과
  • 두번째 풀이 : 2차원 테이블을 1차원으로 수정하여 풀이 -> 시간 초과

한 시간 반 정도 붙잡고 있다가 도저히 안풀려 검색해보니 비트마스크 개념을 도입하는 사람들이 많았다.

모든 자연수는 2의 거듭제곱의 합으로 나타낼 수 있기 때문에 물건을 1개씩 추가해주는 것이 아니라 2의 거듭제곱씩 추가해도 모든 수를 고려할 수 있다.

만약 같은 물건 15개가 있다고 생각해보자. 15는 1 + 2 + 4 + 8 이기 때문에 물건을 1개, 2개, 4개, 8개 추가한 경우를 모두 DP 테이블에 갱신시켜주면 됐다.

 

12920번: 평범한 배낭 2

첫 번째 줄에 N, M (1 ≤ N ≤ 100, 1 ≤ M ≤ 10,000) 이 빈칸을 구분으로 주어진다. N은 민호의 집에 있는 물건의 종류의 수이고 M은 민호가 들 수 있는 가방의 최대 무게다. 두 번째 줄부터 N개의 줄에

www.acmicpc.net