【 Backpack problem series 】 a classic backpack problem
This series is based on the study of Gongshui Sanye’s big wechat public number – backpack problem after sorting out, if there is any violation, please inform us
[Blog link]
A path to learning at 🐔
Classic backpack problem
[B].
There are values. Length items and a backpack with a capacity of N. There is one and only one of each item. The weights are **weights[I]**, and the values are **values[I]**. Solve which items to put into the backpack so that the total volume of these items does not exceed the backpack capacity, and the total value of the maximum. Example 1: Input: V = 4, values = [4,2,3], weights = [4,2,3] Output: 4 Explanation: Select only the first item to maximize the value. Example 2: input: V = 5, values = [4,2,3], weights = [4,2,3] output: 5 explanation: do not select the first item, select the second and third items to maximize the value.Copy the code
[D].
-
So when we’re dealing with dp problems and we can’t think of the DP equation directly at first, we can think of DFS recursion to determine the recursive equation
-
Int DFS (int n,int I,int [] values, int[] weights)
-
N (current capacity), I (current item)
-
Therefore, the DP equation can be generated by two variable parameters
-
Dp [I][j] represents the highest value obtained for I items at maximum weight J before use
-
When I = 0, we need to initialize dp array dp[0][j]
-
The derivation of dynamic equation can be analyzed according to the following ideas
-
Face value whether I, need to decide to take * * (dp [I] [j – weight [I]] + val [I]) * * or don’t take (dp) [j] [I – 1] whose value is higher
-
dp[i][j] = Math.max(dp[i-1][j],dp[i][j-weights[i]] + values[i]) Copy the code
public int getMaxValue(int[] value, int[] weights, int n) {
int[][] dp = new int[value.length][n + 1];
// Boundary conditions
for (int i = 0; i < n; i++) {
dp[0][i] = (weights[0] <= i) ? value[0] : 0;
}
for (int i = 1; i < value.length; i++) {
int val = value[i];
for (int j = 1; j <= n; j++) {
if (j >= weights[i]) {
// Select and deselect the maximum value of the current item
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weights[i]] + val); }}}return dp[value.length - 1][n];
}
Copy the code
Time complexity O(N*C) N represents the number of items and C represents the maximum weight
Optimization 1: a combination of scrolling arrays and dynamic programming optimizes storage space
- According to the above recursive equation, it can be seen that DP [I][j] is only related to DP [i-1][j]. Such a dynamic programming problem can be solved by rolling the array dp equation
- Define **dp[2][j]** to store the previous bit’s maximum value solution and the current bit’s maximum value solution
- How do we traverse two elements we can translate traverse by parity
public int getMaxValue(int[] values, int[] weights, int n) {
int[][] dp = new int[2][n + 1];
for (int i = 0; i < n; i++) {
dp[0][i] = (weights[0] <= i) ? values[0] : 0;
}
for (int i = 1; i < values.length; i++) {
for (int j = 0; j <= n; j++) {
// Do not select the current item
int tempF = dp[(i - 1) & 1][j];
// Select the current item
int tempT = j >= weights[i] ? dp[(i - 1) & 1][j - weights[i]] + values[i] : 0;
dp[i & 1][j] = Math.max(tempF, tempT); }}return dp[(values.length - 1) & 1][n];
}
Copy the code
Time complexity O(N*C) N represents the number of items and C represents the maximum weight
Optimization two: clear dependence, space optimization again
- Based on the above optimization, you can see that the current maximum value is related to only two determined values
- Is the dp [I] [j] only dp [j] and [I – 1] * * dp [I] [j – weights [I]] * * two values
public int getMaxValue(int[] values, int[] weights, int n) {
int[] dp = new int[n + 1];
for (int i = 0; i < values.length; i++) {
for (int j = n; j >= weights[i]; j--) {
// do not select this item
int x = dp[j];
// Select this item
inty = dp[j - weights[i]] + values[i]; dp[j] = Math.max(x, y); }}return dp[n];
}
Copy the code