多重背包

有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 }

 

多重背包问题跟完全背包简直如出一辙,仅仅是比完全背包多一个限制条件而已。
posted on 2021-03-24 15:41  qiwa-hk  阅读(59)  评论(0)    收藏  举报