参考 : 代码随想录
理论知识
动态规划问题,将拆解为如下五步曲,这五步都搞清楚了,才能说把动态规划真的掌握了!
- 确定dp数组(dp table)以及下标的含义
- 确定递推公式
- dp数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
发出这样的问题之前,其实可以自己先思考这三个问题:
- 这道题目我举例推导状态转移公式了么?
- 我打印dp数组的日志了么?
- 打印出来了dp数组和我想的一样么?
如果这灵魂三问自己都做到了,基本上这道题目也就解决了
01背包问题
详解:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
|
public class beibao {
public static void main(String[] args) { int[] weight = {1,3,4}; int[] value = {15,20,30}; int bagSize = 4; testWeightBagProblem(weight,value,bagSize); }
public static void testWeightBagProblem(int[] weight , int[] value, int bagSize){ int[][] dp = new int[weight.length][bagSize + 1];
for(int j =weight[0]; j <= bagSize;j++){ dp[0][j] = value[0]; }
for(int i =1;i < weight.length;i++){
for(int j = 1 ; j <= bagSize;j++){ if(j < weight[i]){ dp[i][j] = dp[i-1][j]; }else{
dp[i][j] = Math.max(dp[i-1][j], dp[i-1][j - weight[i]] + value[i]); } } }
for(int i = 0;i< dp.length;i++){ for(int j =0 ;j< dp[0].length;j++){ System.out.print(dp[i][j] + "\t"); } System.out.println(); }
} }
|
优化: 使用一维数组
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| package First;
import java.util.*;
public class yiweibeibao { public static void main(String[] args) { int[] weight = {1,3,4,5,6,8}; int[] value = {15,20,30,40,45,20}; int bagSize = 4; WeightBagProblem(weight,value,bagSize); }
public static void WeightBagProblem(int[] weight, int[] value, int bagSize) { int[] dp = new int[bagSize + 1]; for(int i =0 ;i < weight.length;i++){ for(int j=bagSize ;j >= weight[i];j--){ dp[j] = Math.max(dp[j] , dp[j - weight[i]] + value[i]); System.out.println(Arrays.toString(dp)); } System.out.println(); } for (int j = 0; j <= bagSize; j++){ System.out.print(dp[j] + " "); } } }
|
运行结果