 Edit by zhusenlin HDU
01 A backpack is a backpack with several items taken out of M and placed in W space. The size of each item is C1, C2 ,..., Cn, corresponding value: W1, W2 ,..., Wn. Solving these items into a backpack can maximize the total value.
Dynamic Planning (DP ):
1) subproblem definition: F [I] [j] indicates the maximum value that can be obtained when several items are selected from the first I items are placed in a backpack with the free space j.
2) make a decision based on whether to place or not to place the Ith item
(11)
Among them, F [I1] [j] indicates the maximum value of the items selected from the front I1 items in the left space j in the backpack;
F [I1] [jC [I] + W [I] indicates that several items selected from the items in the front I1 are placed into the backpack with the remaining space jC [I] the maximum value that can be obtained plus the value of the Iitem.
The status F [I] [j] when traversing the Ith item based on whether the Ith item is put or not.
Set the number of items to N, the size of the backpack to V, the size of the I item to C [I], and the value of the I item to W [I].
The pseudocode is written as follows:
F[0][] ← {0} F[][0] ← {0} for i←1 to N do for k←1 to V F[i][k] ← F[i1][k] if(k >= C[i]) then F[i][k] ← max(F[i][k],F[i1][kC[i]]+W[i]) return F[N][V]
The preceding pseudocode array is based on the 1 index and the first item index is 1.Time and space complexity are O (VN)
For example, table 11 is a backpack problem data table with a backpack capacity of 10. According to the above solution, the corresponding F [I] [j] can be obtained, as shown in table 12, the maximum value is F [6] [10].
Table 11 knapsack problem data table
Item No. I 
1 
2 
3 
4 
5 
6 
Volume C 
2 
3 
1 
4 
6 
5 
Value W 
5 
6 
5 
1 
19 
7 
Table 12 the largest value table obtained when I selected several items and placed them in a backpack with j Space

0 
1 
2 
3 
4 
5 
6 
7 
8 
9 
10 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
0 
1 
0 
0 
5 
5 
5 
5 
5 
5 
5 
5 
5 
2 
0 
5 
6 
6 
11 
11 
11 
11 
11 
11 
11 
3 
0 
5 
5 
10 
11 
11 
16 
16 
16 
16 
16 
4 
0 
5 
5 
10 
11 
11 
16 
16 
16 
16 
17 
5 
0 
5 
5 
10 
11 
11 
19 
24 
24 
29 
30 
6 
0 
5 
5 
10 
11 
11 
19 
24 
24 
29 
30 
Many articles only find out the maximum value of a backpack, and do not find out which items are selected. I encountered many similar problems before I learned about my backpack. At that time, I only obtained the greatest value or the largest sum, and I was helpless in terms of specific items or paths. I will share with you the details.
The maximum value table obtained based on the algorithm actually contains location information, from F [N] [V] to F [0] [0], where I = N, j = V, if F [I] [j] = F [I1] [jC [I] + W [I] indicates that the package contains I items, j= C [I], whether F [I] [j] and F [I1] [jC [I] + W [I] are not equal, I is reduced by 1, because the Ith item of the 01 backpack is either put or not put, whether put or not it has already been traversed, You need to continue traversing.
The pseudocode for printing items in a backpack is as follows:
i←N j←V while(i>0 && j>0) do if(F[i][j]=F[i1][jC[i]]+W[i]) then Print W[i] j←jC[i] i←i1
Of course, you can also define a twodimensional array Path [N] [V] to store information about the items in the backpack. At the beginning, Path [N] [V] is initialized to 0, when F [I] [j] = F [I1] [jC [I] + W [I], Path [I] [j] is set to 1. Finally, we can obtain the items in the backpack from Path [N + 1] [V + 1] to Path [0] [0. Path [0] [] and Path [] [0] are boundaries.
The pseudocode for adding path information is as follows:
F[0][] ← {0} F[][0] ← {0} Path[][] ← 0 for i←1 to N do for k←1 to V F[i][k] ← F[i1][k] if(k >= C[i] && F[i][k] < F[i1][kC[i]]+W[i]) then F[i][k] ← F[i1][kC[i]]+W[i] Path[i][k] ← 1 return F[N][V] and Path[][]
The pseudocode for printing items in a backpack is as follows:
i←N j←V while(i>0 && j>0) do if(Path[i][j] = 1) then Print W[i] j←jC[i] i←i1
When both the time and space complexity are O (NV, the method of using Path [] [] is obviously more effective than printing by F [I] [j] = F [I1] [jC [I] + W [I ]. spaceconsuming items, path [] [] requires extra space O (NV), but the total space complexity remains unchanged at O (NV ). But the O (V) but cannot use the relational F [j] = F [jC [I] + W [I], rather than using Path.
Next, we will consider how to compress the space to reduce the space complexity.
The time complexity is O (VN), and the space complexity is O (V)
Observation of pseudocode can also be found that F [I] [j] is only related to F [I1] [j] and F [I1] [jC [I, that is, it is only related to the I1 time state, so we only need to use a onedimensional array F [] to save the state F [] When the I1. Assume that F [] of the I1 moment is {a0, a1, a2 ,..., Av}, the k number in F [] of the hard I time should be max (ak, akC [I] + W [I]) max (F [k], F [kC [I] + W [I]). This requires us to traverse V in reverse order, this ensures that F [kC [I] is the value of the I1 moment. If forward traversal is performed, F [0], F [1],… before F [k] is obtained. F [K1] has changed, the memory is not the value of the I1 time, so that F [k] When Using F [KC [I] must be the wrong value. Finally, F [V] is the maximum value.
The equation of state for F [j] is as follows:
(12)
The pseudocode is as follows:
F[] ← {0} for i ← 1 to N do for k ← V to C[i] F[k] ← max(F[k],F[kC[i]]+W[i]) return F[V]
Similarly, how to find the path?
Use the Path [] [] Mark mentioned above to consume space O (NV ). Here, F [j] = F [jC [I] + W [I] cannot be used to determine whether a onedimensional array does not provide enough information to find a twodimensional path.
The pseudocode for adding path information is as follows:
F[] ← {0} Path[][]←0 for i←1 to N do for k←V to C[i] if(F[k] < F[kC[i]]+W[i]) then F[k] ← F[kC[i]]+W[i] Path[i][k] ← 1 return F[V] and Path[][]
The pseudocode of the print path is the same as that of the pseudo code when the preceding space is not compressed, and will not be overwritten here.
The following code provides two methods for testing table 11:
# Include <iostream> # include <cstring> # include "createarray. H" // This header file is used to dynamically create and destroy twodimensional arrays. You can implement using namespace STD by yourself;
// Time complexity O (VN) and space complexity O (VN)
Int package01 (INT weight [], int value [], int nlen, int ncapacity) {int ** table = NULL; int ** Path = NULL; createtwodimarray (table, nlen + 1, ncapacity + 1); // create a twodimensional array createtwodimarray (path, nlen + 1, ncapacity + 1); // create a twodimensional array for (INT I = 1; I <= nlen; I ++) {for (Int J = 1; j <= ncapacity; j ++) {table [I] [J] = table [I1] [J]; path [I] [J] = 0; if (j> = weight [I1] & table [I] [J] <Table [I1] [Jweight [I1] + value [I1]) {table [I] [J] = table [I1] [Jweight [I1] + value [I1]; path [I] [J] = 1 ;}}} int I = nlen, j = ncapacity; while (I> 0 & J> 0) {If (path [I] [J] = 1) {cout <weight [I1] <"; j= weight [I1];} I ;} cout <Endl; int nret = table [nlen] [ncapacity]; destroytwodimarray (table, nlen + 1); // destroy the twodimensional array destroytwodimarray (path, nlen + 1 ); // destroy the twodimensional array return nret ;}
// Time complexity O (VN). The path space complexity is O (v), and the path space complexity is O (VN)
Int package01_compress (INT weight [], int value [], int nlen, int ncapacity) {int * Table = new int [ncapacity + 1]; memset (table, 0, (ncapacity + 1) * sizeof (INT); int ** Path = 0; createtwodimarray (path, nlen + 1, ncapacity + 1 ); // create a twodimensional array for (INT I = 0; I <nlen; I ++) {for (Int J = ncapacity; j> = weight [I]; j ) {path [I + 1] [J] = 0; If (Table [J] <Table [Jweight [I] + value [I]) {table [J] = table [Jweight [I] + value [I]; path [I + 1] [J] = 1 ;}}} int I = nlen, j = ncapacity; while (I> 0 & J> 0) {If (path [I] [J] = 1) {cout <weight [I1] <"; j= weight [I1];} I ;} cout <Endl; int nret = table [ncapacity]; destroytwodimarray (path, nlen + 1); // destroy the twodimensional array Delete [] Table; return nret ;}
Test code
int main(){int Weight[] = {2,3,1,4,6,5};int Value[] = {5,6,5,1,19,7};int nCapacity = 10;cout << Package01(Weight,Value,sizeof(Weight)/sizeof(int),nCapacity) << endl;cout << Package01_Compress(Weight,Value,sizeof(Weight)/sizeof(int),nCapacity) << endl;return 0;}
For some content in this article, refer to "backpack 9 lecture"