/*
背包问题测试:背包问题:给定 n 种物品和一个容量为 C 的背包,物品 i 的重量是 wi,其价值为 vi 。
问:应该如何选择装入背包的物品,使得装入背包中的物品的总价值最大?
设F[n][c]的值表示可放入的物品最大总价值,i为物品编号,j为当前背包容量.
理解:第j件物品是否应该放入背包?
1、若当前背包总容量小于第j件物品容量,则不放入。f[i][j] = f[i-1][j]
2、若当前物品满足放入背包的条件:j(当前总容量)>wi(物品重量)。
则f[i][j] = max(f[i-1][j-wi]+wi,f[i-1][j])
惯性思维误区:认为放进第i件物品时一定比前面的总价值大。即错误的认为f[i-1][j-wi]等于f[i-1][j]
我的理解:背包问题是从当前的总容量考虑,并非当前的剩余容量。
当确认放进第i件物品时,背包容量立即变为j-wi,然后再从1....i-1中物品中选取,最终得到最大价值
*/
@Test
public void BagProblem(){
final int number = 5;
final int totalWeight = 20;
int weight[] = {0,6,4,11,6,9}; //物品重量
int value[] = {0,6,3,5,4,6}; //物品价值
int[][] f = new int[number+1][totalWeight+1];
for(int j=1;j<=totalWeight;j++){
for(int i=1;i<=number;i++){
if (j<weight[i])
f[i][j] = f[i-1][j];
else
f[i][j] = Math.max(f[i-1][j],f[i-1][j-weight[i]]+value[i]);
}
}
//以下代码输出f数组
for (int i=1;i<=totalWeight;i++){
System.out.print(" j="+i);
}
System.out.println();
for (int i=1;i<=number;i++){
System.out.print("i="+i);
for (int j=1;j<=totalWeight;j++){
System.out.print(" "+f[i][j]);
}
System.out.println();
}
System.out.println("总重量为:"+f[number][totalWeight]);
}