DP analysis
1. Knapsack problem (choice question)
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.
-
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 lastf[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 isf[i - 1][j - v[i]]
, and finally the value of w[i] is added.