Complete Backpack—Dynamic Programming

1. Overview of the backpack problem

Please add image description
As shown in the picture, there is only one difference between the complete backpack and the 01 backpack: you can only take one item of each item in the 01 backpack, but you can take countless items of each item in the complete backpack. To solve the complete knapsack problem, you must first understand the 01 knapsack. If you are unclear, you can read my article 01 knapsack—dynamic programming .

2. Example questions

weight value
Item 0 1 15
Item 1 3 20
Item 2 4 30

The maximum capacity of the backpack is 4.

Each item has two states, "take" or "not take". The backtracking method can be used to violently enumerate the permutations and combinations of the status of all items, and compare it with the maximum capacity of the backpack to find the maximum value. The time complexity is O ( 2 n ) O(2^n)O(2n )is at exponential level, so dynamic programming solution is required for optimization.

3. One-dimensional array (rolling array) solution to complete knapsack

1. From 01 backpack to complete backpack

From 01 Knapsack - Dynamic Programming , we can know that a one-dimensional DP array is a simplification of a two-dimensional DP array. Therefore, the two-dimensional DP array is essentially the same as the one-dimensional DP array. This article only introduces the one-dimensional DP array solution to the complete knapsack.

For the 01 backpack, the inner loop jis traversed backwards from large to small. The reason for this is to prevent dp[j]the previous elements from being contaminated and avoid the problem of accumulation (each item can only be selected once). For a complete backpack, each item can be selected countless times. jTraversing from front to back means jtrying to put items into each capacity ito see if it will increase the total value. It does not pay attention to ithe number of items put in. . Therefore, there is only one difference between the code of the complete backpack and the 01 backpack, which is jthe traversal order.

// 01背包遍历
for(int i = 0; i < weight.size(); i++) {
    
     // 遍历物品
    for(int j = bagWeight; j >= weight[i]; j--) {
    
     // 遍历背包容量
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
    }
}
// 完全背包遍历
// 先遍历物品,再遍历背包
for(int i = 0; i < weight.size(); i++) {
    
     // 遍历物品
    for(int j = weight[i]; j <= bagWeight ; j++) {
    
     // 遍历背包容量
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

    }
}

2. The difference between 01 backpack and complete backpack—traversal order

The traversal order of 01 backpack is:

In the two-dimensional DP array, you can traverse the items first or the backpack capacity first;

In a one-dimensional DP array, items must be traversed first before traversing the backpack capacity. Only in this way can you ensure that each item is selected only once.

For a complete backpack, there is no restriction that you can only select it once, so is it okay to traverse the backpack capacity first and then traverse the items? The answer is yes. Because it is calculated based on the DP array element corresponding to dp[j] the subscript . jJust make sure that the DP array before the subscript jis calculated. Figure 1 traverses the backpack capacity first and then traverses the items; Figure 2 traverses the items first and then traverses the backpack capacity.


Please add image description

// 先遍历物品,再遍历背包
for(int i = 0; i < weight.size(); i++) {
    
     // 遍历物品
    for(int j = weight[i]; j <= bagWeight ; j++) {
    
     // 遍历背包容量
        dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);

    }
}

// 先遍历背包,再遍历物品
for(int j = 0; j <= bagWeight; j++) {
    
     // 遍历背包容量
    for(int i = 0; i < weight.size(); i++) {
    
     // 遍历物品
        if (j - weight[i] >= 0) 
            dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
    }
}

Guess you like

Origin blog.csdn.net/qq_44733706/article/details/129190143