*----- Edit by ZhuSenlin HDU*

I have discussed in detail the full backpack problem in my blog "backpack problem-" full backpack "details and implementation (including how to solve the specific backpack items, at the same time, in the blog "backpack problem-" 01 backpack "Optimal Solution Total Number Analysis and Implementation", we also summarized the implementation of the 01 backpack optimal solution total number. Here we provide the optimal solution for the complete backpack by imitating the total number of optimal solutions of the 01 backpack.

Rewrite the state and state equation of the Dynamic Planning of the complete backpack:

The full backpack is in N**Type**Several items (the same item can be selected multiple times) are selected and placed in a backpack with a space of V.**Type**The size of an item is C1, C2 ,..., Cn, corresponding value: W1, W2 ,..., Wn. Solve how to install items to maximize the total value of items in the backpack.

Set the item type to N, the backpack capacity to V, the volume of each item to C [I], and the value to W [I].

Sub-question definition: F [I] [j] indicates the first I**Type**The maximum value that can be obtained by selecting items in an item and placing them in a backpack with the free space j.

The state equation is:

(2-2)

In the article "backpack problem-" 01 backpack "Optimal Solution Total Number Analysis and Implementation", G [I] [j] represents the total number of solutions for F [I] [j. Here we also make the same definition, so the final result should be G [N] [V].

**From 01 to G [I] [j] after a full backpack?**

**For the 01 backpack**, G [I] [j] method as follows (from: backpack problem -- Analysis and Implementation of the "01 backpack" optimal solution):

If F [I] [j] = F [I-1] [j] and F [I] [j]! = F [I-1] [j-C [I] + W [I] indicates that in the status [I] [j], only the placement of the item before the I-1 will maximize the value, therefore, if I items are not placed, the number of solutions to the State [I] [j] should be equal to the number of solutions in the [I-1] [j] State, that is**G [I] [j] = G [I-1] [j]**;

If F [I] [j] = F [I-1] [j-C [I] + W [I] and F [I] [j]! = F [I-1] [j] indicates that in the status [I] [j], only the addition of the I-th item will maximize the total value, then the number of solutions should be equal to the number of [I-1] [j-C [I], that is**G [I] [j] = G [I-1] [j-C [I]**;

If F [I] [j] = F [I-1] [j-C [I] + W [I] and F [I] [j] = F [I-1] [j] indicates that the status [I-1] [j] can be reached by the State [I] [j], the status [I-1] [j-C [I] can also be used to arrive at the status [I] [j] When I item is added, both cases make the greatest value and the two cases are mutually exclusive, so the total number of solutions is**G [I] [j] = G [I-1] [j-C [I] + G [I-1] [j]**.

**For full backpacks**We can also determine the conditions based on the state equation:

If F [I] [j] = F [I-1] [j] and F [I] [j]! = F [I] [j-C [I] + W [I], indicating that there is no type I in the backpack, that is to say, the type of the backpack is still composed of the former I-1, so there should be**G [I] [j] = G [I-1] [j]**;

If F [I] [j] = F [I] [j-C [I] + W [I] and F [I] [j]! = F [I-1] [j], it indicates that there must be the I type of items in the backpack so that the backpack reaches the maximum state of [I] [j,**G [I] [j] = G [I] [j-C [I]**;

If F [I] [j] = F [I] [j-C [I] + W [I] and F [I] [j] = F [I-1] [j], this indicates that the existence of I and the absence of I in the backpack can reach the maximum value, so the number of this solution should be superimposed by the two, because the two situations are mutually exclusive, that is**G [I] [j] = G [I-1] [j] + G [I] [j-C [I]**.

The pseudocode is as follows (note the difference between the package and 01 ):

F[0][] ← 0 F[][0] ← 0 G[][ ] ← 1 for i ← 1 to N do for j ← 1 to V F[i][j] ← F[i-1][j] G[i][j] ← G[i-1][j] if (j >= C[i]) if (F[i][j] < F[i][j-C[i]]+W[i]) then F[i][j] ← F[i][j-C[i]]+W[i] G[i][j] ← G[i][j-C[i]] else if (F[i][j] = F[i][j-C[i]]+W[i]) then G[i][j] ← G[i-1][j]+G[i][j-C[i]] return F[N][V] and G[N][V]

Similarly, the above method is required when saving the state F [] [] and G [] []**Space complexity of O (NV)**Below we will optimize the space replication.

** **

**The compression space complexity is O (V)**

F [I] [j] and G [I] [j] are only related to the states of F [I-1] [] and G [I-1, therefore, we can use two one-dimensional arrays F [] and G [] to replace the two-dimensional arrays F [] [] and G [] [].

The pseudocode is provided directly:

F[] ← 0 G[] ← 1 for i ← 1 to N do for j ← C[i] to V if (F[j] < F[j-C[i]]+W[i]) then F[j] ← F[j-C[i]]+W[i] G[j] ← G[j-C[i]] else if (F[j] = F[j-C[i]]+W[i]) then G[j] ← G[j]+G[j-C[i]] return F[V] and G[V]

Compared with the total number of optimal solutions for the 01 backpack, the above pseudo code just changed the traversal order of C [I] and V, for more information about the specific ideas, see the blog "backpack problem-" full backpack "for details and implementation (including solutions for specific backpack items)".

** **

**The following code details two types of spatial complexity of a data table:**

Full backpack data table (Backpack capacity: 10)
Item No. I |
1 |
2 |
3 |

Volume C |
2 |
2 |
2 |

Value W |
5 |
5 |
5 |

Because there are generally many solutions for a full backpack, only three items are listed here for your convenience.

# Include <iostream> # include <cstring> # include "CreateArray. h" // This header file is used to dynamically create and destroy two-dimensional arrays. You can implement using namespace std by yourself;

**// Time complexity O (VN) and space complexity O (VN)**

Int Package02Optimal (int Weight [], int Value [], int nLen, int nCapacity) {int ** MaxValueTable = NULL; int ** OptimalTable = NULL; CreateTwoDimArray (MaxValueTable, nLen + 1, nCapacity + 1); // create the maximum value table CreateTwoDimArray (OptimalTable, nLen + 1, nCapacity + 1 ); // create the optimal total number of solutions table // initiallize all OptimalTable [] [] with 1for (int I = 0; I <= nLen; I ++) for (int j = 0; j <= nCapacity; j ++) OptimalTable [I] [j] = 1; for (int I = 1; I <= nLen; I ++) {for (int j = 1; j <= nCapacity; j ++) {MaxValueTable [I] [j] = MaxValueTable [I-1] [j]; optimalTable [I] [j] = OptimalTable [I-1] [j]; if (j> = Weight [I-1]) {if (MaxValueTable [I] [j] <MaxValueTable [I] [j-Weight [I-1] + Value [I-1]) {MaxValueTable [I] [j] = MaxValueTable [I] [j-Weight [I-1] + Value [I-1]; optimalTable [I] [j] = OptimalTable [I] [j-Weight [I-1];} else if (MaxValueTable [I] [j] = (MaxValueTable [I] [j-Weight [I-1] + Value [I-1]) {OptimalTable [I] [j] = OptimalTable [I-1] [j] + OptimalTable [I] [j-Weight [I-1] ;}} cout <endl <"OptimalCount:" <OptimalTable [nLen] [nCapacity] <endl; int nRet = MaxValueTable [nLen] [nCapacity]; DestroyTwoDimArray (MaxValueTable, nLen + 1); // destroy the maximum value table to prevent memory leakage DestroyTwoDimArray (OptimalTable, nLen + 1); // destroy the optimal solution table to prevent memory leakage return nRet ;}

**// Time complexity O (VN), space complexity O (V)**

int Package02Optimal_Compress(int Weight[], int Value[], int nLen, int nCapacity){int * MaxValueTable = new int [nCapacity+1];memset(MaxValueTable,0,(nCapacity+1)*sizeof(int));//initiallize all OptimalTable[] with 1int* OptimalTable = new int[nCapacity+1];for(int i = 0; i <= nCapacity; i++)OptimalTable[i] = 1;for(int i = 0; i < nLen; i++){for(int j = Weight[i]; j <= nCapacity; j++){if(MaxValueTable[j] < MaxValueTable[j-Weight[i]]+Value[i]){MaxValueTable[j] = MaxValueTable[j-Weight[i]]+Value[i];OptimalTable[j] = OptimalTable[j-Weight[i]];}else if(MaxValueTable[j] == MaxValueTable[j-Weight[i]]+Value[i])OptimalTable[j] = OptimalTable[j-Weight[i]]+OptimalTable[j];}}cout << endl << "OptimalCount:" << OptimalTable[nCapacity] << endl;int nRet = MaxValueTable[nCapacity];delete [] OptimalTable;delete [] MaxValueTable;return nRet;}

**// Test code**

int main(){//int Weight[] = {3,2,5,1,6,4};//int Value[] = {6,5,10,2,16,8};int Weight[] = {2,2,2};int Value[] = {5,5,5};int nCapacity = 10;cout << "MaxValue:" << Package02Optimal(Weight,Value,sizeof(Weight)/sizeof(int),nCapacity) << endl;cout << "MaxValue:" << Package02Optimal_Compress(Weight,Value,sizeof(Weight)/sizeof(int),nCapacity) << endl;return 0;}

For the above content, refer to "backpack 9 lecture".