Hdu 2602 01 backpack
Background: if you have not carefully read the question, the wrong input order is skipped once. I made the first DP question myself. After reading this question for a long time, I finally understood the 01 backpack mentioned in Chapter 9.
Learning:
1.01 A backpack features a limited number of items. You can choose to put or not to put each item. The name 01 indicates 1 (Put) 0 (not put.
The traditional packaging method uses a two-dimensional array. The time and space are O (VN). When j is written from 0 ..... n, for n ..... after 0, the space is optimized to O (V), and then two pruning operations are performed. Here we will explain the principle of pruning:
int min=max(list[1][i],v-sum(i,n-1));
Analysis: the specific method for pruning is to change the lower limit of j to 0 and to min. Here, list [1] [I] is the cost of the currently selected item (item I). If the remaining volume is smaller than list [1] [I], it means no matter how
It is also impossible to select the I-th item, because it cannot be placed, so the list [1] [I]... 0 should be the last content, and there is no need to modify it. Among them, the v-sum (I, n-1) backpack 9 will be reserved for thinking questions. The author will explain the following: the optimization solution is: j must be greater than or equal to v-sum (I, n-1 ), in the opposite direction: If j is smaller than v-sum (I, n-1), then when I is not placed, the remaining capacity of the backpack is enough to put down the I to n backpacks, the result is, of course, the total value from the I to the n is the largest, and no judgment is required. In other words, for each backend backpack, F [j] (not put) (F [j] = F [j-list [1] [I]) <= F [j-list [1] [I] + list [0] [I], that is, you only need to select the I number on the right each time.
#include
using namespace std;int list[2][1000],F[1001];int sum(int i,int k){ int ans=0; for(int j=i;j <= k;j++) ans+=list[1][j]; return ans;}void dp(void){ int v,n; cin >> n >> v; for(int i=0;i < v+1;i++) F[i]=0; for(int i=0;i < 2;i++) for(int j=0;j < n;j++) cin >> list[i][j]; for(int i=0;i < n;i++){ int min=max(list[1][i],v-sum(i,n-1)); for(int j=v;j >= min;j--) F[j]=max(F[j],F[j-list[1][i]]+list[0][i]); } cout << F[v] << endl;}int main(void){ int tests; cin >> tests; while (tests--) dp(); return 0;}