PS: The title of this article comes from the courseware of Zhang Haowei (Zhang Guoyi) dalao of Peking University.
I.0/1 Backpack
There are n items, a knapsack of volume m, each item has a value vi, and a volume ti,
select a number of items such that the sum of the values is maximum when the sum of the volumes does not exceed m.
n<=1000, m<=10000.
Normal 0/1 backpack.
II.0/1 Backpack+
n <= 1000, vi <= 10。
According to the idea of memory search:
Let x=current item number, y=sum of current volume, z=sum of current value
When x and z are fixed, the smaller the y, the better. So take x and z as the state and y as the value of dp.
O(nvi)
III.0/1 Backpack++
n<=40
This question has nothing to do with DP. The correct solution is a halved search.
O(2^(n/2)*n) Search in half All items are divided into two halves, and the two halves are searched separately, a scheme <==> Take one on each side and put it together
IV.0/1 Backpack+++
sum of values modulo p max
n<=40 p<=10000
because (a+b+c)%p <==> ((a+b)%p+c)%p
So the value vi<=10000 at the same time
O (eg)
V.0/1 Backpack++++
For any ith item, find the maximum value when the ith item must not be in the backpack.
n<=1000, m<=10000.
The maximum value of an item k when it is not in the backpack is equivalent to dividing the maximum value into the maximum value of 1~k-1 and the maximum value of k+1~n.
We can calculate the maximum value of a prefix and the maximum value of a suffix in O(nm).
Then enumerate the volume of the following divisions and calculate ans.
For the first i items, the sum of volumes is j, and what is the maximum sum of values A prefixed collection of items suffix collection of items If the xth item is gone, 1 ~x- 1 + x+ 1 ~ n and a suffix. How much volume are allocated to each of them. enumerate Enumerate x, and then enumerate how much volume is assigned to the prefix, find max f[i][j] 1 ~ i volume is the maximum value of j g[i][j] i ~ n volume is the maximum value of j for (x=1; x<=n; x++) { ans=0; for (j=0; j<=m; j++) years =max(years,f[ x- 1 ][j]+g[x+ 1 ][m- j]); cout<<ans<<endl; }
VI.0/1 Backpack +++++
Output Scheme
• n<=10000, m<=10000.
• TL=2s
• ML=1M
General 0/1 backpack output scheme
for (i=1; i<=n; i++) { for (j=0; j<=m; j++) { dp[i][j]=dp[i-1][j]; g[i][j]=j; if (j>=w[i]) if (dp[i-1][j-w[i]]+v[i]>dp[i][j]) { dp[i][j]=dp[i-1][j-w[i]]+v[i]; g[i][j]=j-w[i]; } } } // g[i][j] : dp[i][j] 由 dp[i-1][g[i][j]]转移得到 j=m; for (i=n; i>=1; i--) { if (j!= g[i][j]) the i-th item is selected j=g[i][j]; }
However, this question is very conscientious to set the memory to 1M, which means that we cannot open a two-dimensional array, that is, we can only use a one-dimensional array to store the solution.
Here zhw introduces a subtle approach:
g[i] means that dp[i][current volume v] is transferred from dp[i/2][g[i]], and then divides and conquers continuously.
The final segmented rectangle gets smaller and smaller, eventually forming a path from 1 to n.
In this way, the optimal solution is found within the space complexity of O(M).