8.11动态规划例题:01背包问题

/*
有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背包。
 */

 

 

 1 import java.util.Arrays;
 2 
 3 public class Eight_11动态规划简介及01背包问题 {
 4     static int n = 4; //物品数量
 5     static int C = 5; //背包的承重极限
 6     static int[] w = {2, 1, 3, 2}; //重量表
 7     static int[] v = {3, 2, 4, 2}; //价值表
 8     static int[][] res = new int[n][C+1];
 9 
10     private static int dfs(int i, int c) {
11         if(c <= 0)
12             return 0; //装不下了
13         if(i == n)
14             return 0; //没物品可选择了
15         
16         int v2 = dfs(i+1,c);
17         if(w[i] <= c){
18             int v1 = v[i]+dfs(i+1,c-w[i]);
19             return Math.max(v1, v2);
20         }else{
21             return v2;
22         }
23     }
24     
25     //记忆化递归 重叠子问题不重复求解
26     private static int m(int i, int c) {
27         if(c <= 0)
28             return 0; //装不下了
29         if(i == n)
30             return 0; //没物品可选择了
31         
32         //1.计算之前先查询
33         if(res[i][c] >= 0)
34             return res[i][c];
35                 
36         int v2 = m(i+1,c);
37         int ans;
38         if(w[i] <= c){
39             int v1 = v[i]+m(i+1,c-w[i]);
40             ans = Math.max(v1, v2);
41         }else{
42             ans = v2;
43         }
44         
45         //2.计算之后做保存
46         res[i][c] = ans;
47         return ans;
48     }
49     public static void main(String[] args) {
50         
51         int c = C;
52         System.out.println(dfs(0,c));
53         
54         c = C;
55         for(int i = 0; i < n; i++){
56             Arrays.fill(res[i], -1); //初始化为-1
57         }
58         System.out.println(m(0, c));
59     }
60 }

 

posted @ 2020-04-30 14:05  GrnLeaf  阅读(465)  评论(0编辑  收藏  举报