Understanding the DP knapsack problem

DP analysis

1. Knapsack problem (choice question)

Insert image description here

Input sample

4 5
1 2
2 4
3 4
4 5

Output sample:

8

2. Key points analysis

  • Features: Each item can only be used once

Important variables & formula explanations

  • f[i][j]:Represents the set of all selection methods that only select the first i items and the total volume ≤ j. Its value is the maximum value of each selection method in this set. (Note: The two-dimensional array f here can Think of it as a function that seeks the maximum value, but there is no need to implement it. It can be regarded as the left and right sides of the function canceling out . For ease of understanding, you can treat it directly as the maximum value )
  • State transition equation: f[i][j]= max( f[i-1][j], f[i-1][j-v[i]]+w[i])
  • f[i-1][j]:Do not select the maximum value in the set of the i-th item.
  • f[i-1][j-v[i]]+w[i]:Select the set of the i-th item, but it is not easy to find the attributes of the set directly. Let’s take a roundabout way here. First, subtract the volume of the i-th item and find the maximum value of the selection method in the remaining set.
#include <iostream>

using namespace std;

const int N = 1010;

int n, m;
int v[N], w[N];
int f[N][N];
int main()
{
    cin >> n >> m;
    for (int i = 1; i <= n; i++)
    {
        cin >> v[i] >> w[i];
    }

    for (int i = 1; i <= n; i++)
    {
        for (int j = 0; j <= m; j++)
        {
            //未选第i个元素
            f[i][j] = f[i - 1][j];
            if (j >= v[i])
                f[i][j] = max(f[i][j], f[i - 1][j - v[i]] + w[i]);
        }
    }
    cout << f[n][m] << endl;
    return 0;
}

3. Understand ideas

  • The i-th item is either selected or not.Insert image description here

  • At the beginning, I was also very fascinated by this algorithm. I didn't know f[i][j]why it could mean that the total volume of the first i items was less than the maximum value of j . Later I slowly understood that at the beginning it can be seen as the existence of this function that seeks the maximum value. int Fmax(int ​​i, int j); (No specific implementation details are needed here) , find the maximum value excluding the i-th, and the maximum value excluding the i-th. Taking the maximum of the two is what is needed.

  • for (int i = 1; i <= n; i++)
    for (int j = 0; j <= m; j++); This loop traverses the maximum value of all possible results. And put the maximum value of each result in a two-dimensional array. The last f[n][m]represents the maximum value among all items. Direct output.

  • Here we divide the set of maximum results into two parts. 1. If the i-th item is not selected, the maximum value is the maximum value of the previous i-1 items f[i-1][j]. 1. The i-th item is selected. Since the i-th item is selected, we extract the i-th item, then the maximum value of the first i-1 items is f[i - 1][j - v[i]], and finally the value of w[i] is added.

Guess you like

Origin blog.csdn.net/qq_45372719/article/details/108726406