AOJ0042 A Thief
問題リンク A Thief
- 解法
ナップサック問題です。DPで解きます。
dp[i][j]はi番目までのアイテムを使って重さj以下の中で得られる最大の価値
を表します。
漸化式は
dp[i][j] = Max{
dp[i-1][j] : i番目のアイテムを採用しない
dp[i-1][ j-w[i] ] + v[i] : i番目のアイテムを採用する
}
- ソース
import java.util.Scanner; //A Thief public class AOJ0042 { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int Case = 1; while(true){ int W = sc.nextInt(); if(W==0)break; int n = sc.nextInt(); int[] w = new int[n+1]; int[] v = new int[n+1]; for(int i=1;i<=n;i++){ String[] s = sc.next().split(","); v[i] = Integer.parseInt(s[0]); w[i] = Integer.parseInt(s[1]); } int[][] dp = new int[n+1][W+1]; int maxV = Integer.MIN_VALUE; int minW = Integer.MAX_VALUE; for(int i=1;i<=n;i++){ for(int j=1;j<=W;j++){ if(j-w[i]>=0){ dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j-w[i]]+v[i]); if(maxV < dp[i][j]){ maxV = dp[i][j]; minW = j; } else if(maxV == dp[i][j]){ minW = Math.min(minW, j); } } else dp[i][j] = dp[i-1][j]; } } System.out.println("Case " + Case++ + ":\n" + maxV + "\n" + minW); } } }