描述:
有N 种物品,第i 种物品的重量为wi,价值为vi,每种物品只有一个。背包能承受的重量为
W。将哪些物品装入背包可使这些物品的总重量不超过背包容量,且价值总和最大?
输入:
第1 行包含一个整数T,表示有T 组测试用例。每组测试用例有3 行,第1 行包含两个整数
N;W(N 1000;W 1000) 分别表示物品的种数和背包的容量,第2 行包含N 个整数表示每种物
品的价值,第3 行包含N 个整数表示每种物品的重量。
输出:
每行一个整数,表示价值总和的最大值。
样例输入
15
10
1 2 3 4 5
5 4 3 2 1
样例输出
14
分析:
由于每种物品仅有一个,可以选择装或者不装。
定义状态f[i][j],表示“把前i 个物品装进容量为j 的背包可以获得的最大价值”,则其状态转
移方程便是:
dp[i][j]=max{dp[i-1][j],dp[i-1][i-w[i]]+v[i]}
这个方程理解如下,把前i 个物品装进容量为j 的背包时,有两种情况:
• 第i 个不装进去,这时所得价值为:dp[i-1][j]
• 第i 个装进去,这时所得价值为:dp[i-1][i-w[i]]+v[i]
java实现代码如下:
import java.util.Scanner;
import java.util.Scanner;
/**
*
* @author Administrator
*/
public class Knapsack01 {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
int num = scan.nextInt();
while (num-- != 0) {
int n = scan.nextInt(); //种类数
int m = scan.nextInt(); //背包容量
int[] w = new int[n + 1]; //物品大小
int[] v = new int[n + 1]; //物品容量
int[][] dp = new int[n + 1][m + 1];
for (int i = 1; i <= n; i++) {
w[i] = scan.nextInt(); //物品大小
}
for (int i = 1; i <= n; i++) {
v[i] = scan.nextInt(); //物品容量
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
dp[i][j] = dp[i - 1][j];
if (j >= w[i]) {
dp[i][j] = Math.max(dp[i][j], dp[i - 1][j - w[i]] + v[i]);
}
System.out.print(String.format("%4d", dp[i][j]));
}
System.out.println();
}
System.out.println(dp[n][m]);
}
}
}