多重背包
有N种物品和一个容量为T的背包,第i种物品最多有M[i]件可用,价值为P[i],体积为V[i],
求解:选哪些物品放入背包,可以使得这些物品的价值最大,并且体积总和不超过背包容量。
对比一下完全背包,其实只是多了一个限制条件,完全背包问题中,物品可以选择任意多件,只要你装得下,装多少件都行。
但多重背包就不一样了,每种物品都有指定的数量限制,所以不是你想装,就能一直装的。
参考完全背包的动态规划解法,就很容易写出多重背包的动态规划解法。
自上而下记忆法:
1 public static class MultiKnapsack { 2 private static int[] P={0,2,3,4}; 3 private static int[] V={0,3,4,5}; 4 private static int[] M={0,4,3,2}; 5 private static int T = 15; 6 7 private Integer[][] results = new Integer[P.length + 1][T + 1]; 8 9 @Test 10 public void solve2() { 11 int result = ks2(P.length - 1,T); 12 System.out.println("最大价值为:" + result); 13 } 14 15 private int ks2(int i, int t){ 16 // 如果该结果已经被计算,那么直接返回 17 if (results[i][t] != null) return results[i][t]; 18 int result = 0; 19 if (i == 0 || t == 0){ 20 // 初始条件 21 result = 0; 22 } else if(V[i] > t){ 23 // 装不下该珠宝 24 result = ks2(i-1, t); 25 } else { 26 // 可以装下 27 // 取k个物品,取其中使得价值最大的 28 for (int k = 0; k <= M[i] && k * V[i] <= t; k++){ 29 int tmp2 = ks2(i-1, t - V[i] * k) + P[i] * k; 30 if (tmp2 > result){ 31 result = tmp2; 32 } 33 } 34 } 35 results[i][t] = result; 36 return result; 37 } 38 }
多重背包问题跟完全背包简直如出一辙,仅仅是比完全背包多一个限制条件而已。
浙公网安备 33010602011771号