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