Note: The reference to "backpack Nine talk".
01 knapsack problem
One: Topic description
There are N items and a backpack with a capacity of V. The cost of placing the article I is CI (that is, the volume of the backpack that is occupied), and the value is Wi. The total value of the items loaded into the backpack is the largest.
Second: Basic ideas
01 Backpack is the most basic knapsack problem, the question is characterized by only one piece of each item, you can choose to put or not put, and do not require the backpack must be full, only the final total value of the maximum.
Define the state with sub-problem: f[i][v] Indicates the maximum value that can be obtained when the backpack capacity is V for the first I-item. Imagine putting the "first I item into a backpack with a capacity of V" This sub-problem, if only consider the strategy of article I items (or put or not put), then can be converted into one and the former I -1 items related issues. If I do not put the article I, then the problem is converted to "the first I-1 items into a backpack of capacity V", the value is f[i-1][v]; If you put the article I items, then the problem translates into "The first I-1 items into the remaining capacity of V-ci backpack", at this time to obtain the value of F[i-1][v-ci] + Wi. The state transfer equation can be obtained here:
F[I][V] = max (F[i-1][v], F[i-1][v-ci] + Wi).
Here is a special explanation, this equation is very important, we must know how this is introduced, almost all the knapsack problems in the back are closely related to this equation.
The pseudo code is as follows:
F[0...N][0...V] <---0
For i <---1 to N
For V <---Ci to V
F[I][V] = max (F[i-1][v], F[i-1][v-ci] + Wi);
Specific code:
1 void_01pack (intF[][MAXV],intNintVintC[],intw[]) {2memset (F,0,sizeof(F));3 for(inti =1; I <= N; i++) {4 for(intv = c[i]; V <= v; v++) {5F[I][V] = max (F[i-1][V], F[i-1][v-c[i]] +W[i]); //Put or not put in the choice of the best person6 }7 }8}
Three: Optimization of space complexity
First look at how the above code is implemented. The outermost layer loops, each time the value of the two-dimensional array f[i][0...v] is computed, The F[I][0...V] is obtained from the previous layer of f[i -1][0...V]. So if you change this array to one-dimensional f[v, then you can still keep the last state. The answer is yes. Because of the no-validity of the dynamic programming algorithm, the choice of article I + 1 items Does not affect the selection of item I (that is, its previous item). Then you can follow V <---V in the second cycle above ... 0 in descending order to calculate f[v], the state required to calculate F[V] f[v] and F[v-ci] + Wi is still the last state. After calculating f[v], v , F[v] does not affect F[v '] (V ' < v), because F[v '] only with F[v '] (last value) and F[V-CI] about, while f[v] > f[v '] > f[v '-ci ]. So the state transfer equation can be obtained.
F[V] = max (F[v], F[v-ci] + Wi).
The pseudo code is as follows:
F[0...V] <---0
For i <---1 to N
For V <--- v to Ci
F[V] = max (F[v], F[v-ci] + Wi);
Specific code:
1 void_01pack (intF[],intNintVintC[],intw[]) {2memset (F,0,sizeof(F));3 for(inti =1; I <= N; i++) {4 for(intv = v; V >= C[i]; v--) {5F[I][V] = max (F[v], F[v-c[i]] +w[i]);6 }7 }8}
It can be seen that the efficiency of space optimization from the first state transition equation to the second state transfer equation is quite large:
F[i][v] = max (F[i-1][v], F[i-1][v-ci] + Wi) . ----> F[v] = max (F[v], F[ V-CI] + Wi).
F[V-CI] + Wi is equivalent to f[i -1][v-ci] + Wi. This correctness is established on the premise that the inner cycle is declining. Otherwise, change the inner loop to increment, then f[i][v] is actually by f[i][v] and F[I][V-CI] Launched, this does not conform to the basic idea of the discussion.
def zeroonepack (F, C, W)
for v <--- v to C
F[v] = max (F[v], f[v-c] + W);
f[0...v] <---0
for i <---1 to N
Zeroonepack (F, C[i], w[i]);
Specific code:
1 Const intMAXN =10000;2 intN, V, C[MAXN], W[MAXN];3 4 voidZeroonepack (intF[],intCintW) {//decisions for individual items5 for(intv = v; V >= C; v--) {6F[V] = max (F[v], f[v-c] +W);7 }8 }9 Ten voidSolvintf[]) { Onememset (F,0,sizeof(F)); A for(inti =1; I <= V; i++) { - Zeroonepack (F, C[i], w[i]); - } the}
Four: 01 knapsack problem expansion------details of the initialization
In the question of the 01 knapsack above
Backpack Problem 01 Backpack