/* 背包问题测试:背包问题:给定 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]); }