[01 Backpack Theory] 01 Backpack Problem dp[i][j] (two-dimensional array) <Dynamic Programming Board>

[01 Backpack Theory] 01 Backpack Problem dp[i][j]

There are n items and a backpack that can carry a maximum weight of w.
The weight of the i-th item is weight[i], and the obtained value is value[i].
There is only one item of each item. Find out which items should be put into the backpack and the total value of the items is the largest.

answer

dynamic programming

  • Determine the meaning of the dp array and the subscripts.
    dp[i][j] means that if you take any items with subscripts [0-i] and put them into a backpack with a capacity of j, what is the maximum total value.

  • Determining the recursion formula
    can be derived in two directions dp[i][j]:

    • Without items i: dp[i - 1][j]derived from , that is, the capacity of the backpack is, and the maximum value jwithout items inside , at this time is . (In fact, when the weight of the item is greater than the weight of the backpack, the item cannot be put into the backpack, so the value in the backpack is still the same as before)idp[i][j]dp[i - 1][j] iji
    • Putting items i: dp[i - 1][j - weight[i]]Deduced from , it is the maximum value without putting items when dp[i - 1][j - weight[i]]the backpack capacity is , then ( the value of items ) is the maximum value obtained by putting items in the backpack. So the recursive formula:j - weight[i]idp[i - 1][j - weight[i]] + value[i]ii
      dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
  • How to initialize the dp array.
    Starting from the definition of dp[i][j], if the backpack capacity j is 0, that is, dp[i][0], no matter which items are selected, the total value of the backpack must be 0.
    Insert image description here
    It can be seen from the state transition equation that i is derived from i-1, then it must be initialized when i is 0, dp[0][j], that is: i is 0, and when storing items numbered 0, each capacity The maximum value that the backpack can store.

    • When j < weight[0], dp[0][j] should be 0, because the backpack capacity is smaller than the weight of item number 0.
    • When j >= weight[0], dp[0][j] should be value[0], because the backpack capacity is enough to hold item number 0.
  • Determine the traversal order
    dp[i][j] is derived from its top and upper left. There are two traversal dimensions: items and backpack weight.

  • Take an example to derive the dp array (print the dp array)

public class Solution {
    
    
    public static void main(String[] args) {
    
    
        int[] weight = {
    
    1,3,4};
        int[] value = {
    
    15,20,30};
        int bagSize = 4;
        testWeightBagProblem(weight,value,bagSize);
    }

    /**
     * 动态规划获得结果
     * @param weight  物品的重量
     * @param value   物品的价值
     * @param bagSize 背包的容量
     */
    public static void testWeightBagProblem(int[] weight, int[] value, int bagSize){
    
    

        // 获取物品的数量
        int goodsNum = weight.length;
        //定义dp数组:dp[i][j]表示从下标为[0-i]的物品里任意取,放进容量为j的背包,价值总和最大是多少
        int[][] dp = new int[goodsNum][bagSize + 1];

        // 初始化dp数组,其中默认的值就是0
        for (int i = weight[0]; i <= bagSize; i++) {
    
    
            dp[0][i] = value[0];
        }

//        //遍历,先遍历背包,再遍历物品(竖着遍历)
//        for(int j = 1; j <= bagSize; j++) { // 遍历背包容量
//            for(int i = 1; i < weight.length; i++) { // 遍历物品

        //遍历,先遍历物品,然后遍历背包重量(横着遍历)
        for (int i = 1; i < weight.length; i++) {
    
       // 遍历物品
            for (int j = 1; j <= bagSize; j++) {
    
        // 遍历背包容量
                if (j < weight[i]) {
    
    
                    /**
                     * 当前背包的容量都没有当前物品i大的时候,是不放物品i的
                     * 那么前 i-1个物品能放下的最大价值就是当前情况的最大价值
                     */
                    dp[i][j] = dp[i-1][j];
                } else {
    
    
                    /**
                     * 当前背包的容量可以放下物品i
                     * 那么此时分两种情况:
                     *  1、不放物品i
                     *  2、放物品i
                     * 比较这两种情况下,哪种背包中物品的最大价值最大
                     */
                    dp[i][j] = Math.max(dp[i-1][j] , dp[i-1][j-weight[i]] + value[i]);
                }
            }
        }

        // 打印 dp数组
        for (int i = 0; i < goodsNum; i++) {
    
    
            for (int j = 0; j <= bagSize; j++) {
    
    
                System.out.print(dp[i][j] + "\t");
            }
            System.out.println("\n");
        }
    }
}

Guess you like

Origin blog.csdn.net/qq_44033208/article/details/132639391