/*
有n个重量和价值分别为wi,vi的物品,从这些物品中挑选出总重量不超过W的物品,求所有挑选方案中价值总和的最大值。
1≤n≤100
1≤wi,vi≤100
1≤W≤10000
输入:
n=4
(w,v)={(2,3),(1,2),(3,4),(2,2)}
W=5
输出:
7(选择第0,1,3号物品)
因为对每个物品只有选和不选两种情况,所以这个问题称为01背包。
*/
题解如图:
public class problem_0_1背包问题 {
public static void main(String[] args) {
int[] w = {2, 1, 3, 2};//重量表
int[] v = {3, 2, 4, 2};//价值表
int n = 4;//物品数量
int W = 5;//背包的承重极限
int[][] dp=new int[n][W+1]; //用于记录 f(k,w)情况下的最大价值
for (int j =0; j < dp[0].length; j++) { //初始化0号物品对应各背包容量的情况下的最大价值
if (j>=w[0]) { //背包容量大于0号物品重量,可以放入背包
dp[0][j] = v[0];
}
else{ //背包容量小于0号物品重量,不可以放入背包
dp[0][j]=0;}
}
for (int i = 0; i < n; i++) { //初始化容量为0所对应的最大价值
dp[i][0]=0;
}
for (int i = 1; i <n; i++) { //物品初始可选范围(0-1)
for (int j = 1; j <=W; j++) { //背包当前容量可选范围
if (j >= w[i]) //背包容量大于当前物品重量,可以尝试放入背包
{
int v1=v[i]+dp[i-1][j-w[i]]; //要当前i号物品
int v2=dp[i-1][j]; //不要当前i号物品
dp[i][j]=Math.max(v1,v2); //当前物品所对应的最大价值
}else{ //背包容量小于当前物品重量,不要当前物品
dp[i][j]=dp[i-1][j]; //取当前背包容量下,可选物品范围为i-1情形下的最大值
}
}
}
System.out.println(dp[n-1][W]);
}
}