01 Backpack:
the backpack is a M - piece of items taken out of several pieces placed in the space W Backpack, each item volume is W1,W2 ... Wn , the value corresponding to it is P1,P2 ... Pn . The maximum total value to be obtained.
Basic ideas:
V[i,j] represents the maximum total value of items that were removed from the previous I item and can be loaded into a backpack of volume J .
Initialization conditions:
v[i,0] and V[0,j] are 0, which we can understand in their sense.
State transition equation:
v[i,j]=max{V[i-1,j],v[i-1,j-wi]+pi}, respectively, before and after the article i items are not taken and obtained situation.
The total is the following recursion:
Algorithm Analysis:
The size of the table is N*c, so the time complexity of the algorithm is θ(nC), which can be controlled in θ(C) After some modification of the spatial complexity .
Pseudo code:
C++Code:1.Θ(NC)of space.
for (int i=0;i<=v;i++) dp[0][i]=0; Initial conditions for (int. i=1;i<=n;i++) {for (int v=0; v<=c[i]-1; v++) {dp[i][v]=dp[i-1][v];} for (int v=c[i];v<=v;v++) {Dp[i][v]=max (dp[i-1][v],dp[i-1][v-c[i]]+w[i])}}cout<<dp[n][v]<<endl;
2. Make some optimizations in space, Θ(C)of space.
for (int i=0;i<=v;i++) dp[i]=0; Initial conditions for (int. i=1;i<=n;i++) {for (int v=v;v>=c[i];v--) {Dp[v]=max (dp[v],dp[v-c[i]]+w[i])}}COUT<<DP [v]<<endl;
The basic idea of space optimization:
We know that I of the two-dimensional array in the original code is meant to be a choice in the first I items, and also whether the item I has been selected.
Each decision is made to determine whether the item I is to be selected. For example, for Dp[i-1][v-ci] We know that item I is not selected, and for dp[i][V-CI] We can know that item I has been selected, every time since the previous state ( i-1) to make a decision on whether I want to choose.
The space-optimized code uses a different set of mechanisms to ensure that an item is selected only once.
We can see that v in the second code is looped in reverse order, which is necessary:
This is due to the fact that the state in the first cycle of Dp[v] is recursive by state Dp[v-c] . In other words, this is to ensure that each item is selected only once, to ensure that when considering the " select i item " strategy, it is based on a not already selected Sub-result of I-item DP[V-CI] (if already selected, that is, Dp[v] has completed the state transition equation, will not be carried out ).
Complete Backpack problem:
There are n items and a backpack with a capacity of V. The capacity of the items I put into the article is CI, the value is WI, but the same item can be placed in any number of pieces, asking you how much value you can get.
(1) Two-dimensional array approach: Time complexity O (NVlog2 (v/c[i)) Basic ideas
The difference between this and 01 backpacks is that each item can be selected in any number of pieces, and we only need to make some changes to the state transition equation:
v[i][j]=max{V[i-1][j-k*c[i]]+k*w[i] | 0<=k*c[i]<=v}
Here k is the number of items i have selected, in the program, we only need to do a loop for K , and note that k Range of values, the complete knapsack problem can be solved.
Pseudo Code:
f[0][]←{0} f[][0]←{0} for I←1 to N does for j←1 to V does for k←0 to J/c[i] if (J >= K*c[i])
then F[i][k]←max (F[i][k],f[i-1][j-k*c[i]]+k*w[i]) return F[N][V]
(2) The practice of one-dimensional arrays: The complexity of time O (NV)
Directly put the code:
C + + code:
for (int i=0;i<=v;i++) dp[i]=0; Initial conditions for (int. i=1;i<=n;i++) {for (int v=c[i];v<=v;v++) {Dp[v]=max (Dp[v],dp[v-c[i]]+w[i])}}
Basic ideas:
This is almost the same as the space-optimized code of the backpack, which changes the Cycle Order of V. The purpose of the Front v reverse order loop is to ensure that each item is selected only once, and the number of times each item is selected can be arbitrary after being changed to a positive sequence cycle.
See this example Dp[v-ci] After the selection of article i items into dp[v], and dp[(V+CI)-ci] You can still choose The item I, change to Dp[v+ci].
Multiple backpacks:
There are n items and a backpack with a capacity of V. The capacity of the items I put into the article is CI, the value is WI, but the item I can be put up in mi pieces, ask you how much value you can get.
Basic idea: (1) The practice of two-dimensional arrays
Similar to the previous two types of backpacks, only some changes are made to the state transition equation.
dp[i][v]=max{Dp[i-1][v-k*c[i]]+k*w[i] | 0<=k<=m[i]}
No code is posted.
(2) translates to onBackpack
Space optimization is done by turning it into a backpack and splitting it into a binary approach, splitting it into 1 pieces,2 pieces,4 pieces ... .
for (int i=1;i<=n;i++) {int num=m[i];//num is the number of items for article I by how many pieces for (int k=1;num>=0;k*=2) {int mul=min (k,num)//k is 2 binary, The reason to take the minimum with NUM is similar to 1000 when 512 and 489 is the case, we have to choose 489.for (int j=v;j>=c[i]*mul;j--) {Dp[j]=max (dp[j],dp[j-c[i]*mul]+v[i]* MUL)}num-=mul; To deduct from the total after the pile of the heap }}
Finally, put a code:
#include <iostream>using namespace std; const int N = 3;//Item number const int V = 8;//backpack capacity int Weight[n + 1] = {0,1,2,2};int Value[n + 1] = {0,6,10,20};int Num[n + 1] = {0,10,5,2}; int F[v + 1] = {0};/*f[v]: Represents the maximum benefit of placing the first I item in a backpack with a capacity of V. F[V] = max (F[v],f[v-weight[i]] + value[i]); v is in reverse order */void zeroonepack (int nweight,int nvalue) {for (int v = v;v >= Nweigh t;v--) {F[v] = max (F[v],f[v-nweight] + nvalue);}} /*F[V]: Represents the maximum benefit of placing the first I item in a backpack with a capacity of V. F[V] = max (F[v],f[v-weight[i]] + value[i]), V for the order of increment */void completepack (int nweight,int nvalue) {for (int v = nweight;v <= v;v++) {F[v] = max (F[v],f[v-nweight] + nvalue);}} int Multiknapsack () {int k = 1;int ncount = 0;for (int i = 1;i <= n;i++) {if (weight[i] * Num[i] >= V) {//Full backpack: Such items are in principle Unlimited supply,//At this time meet the conditions weight[i] * Num[i] >= V,//means an unlimited supply until the backpack put up. Completepack (Weight[i],value[i]);} Else{k = 1;ncount = Num[i];while (k <= ncount) {zeroonepack (k * weight[i],k * value[i]); ncount-= K;k *= 2;} Zeroonepack (ncount * weight[i],ncount * value[i]);}} Return F[v];} int main () {Cout<<multiknapsack () <<endl;system ("pause"); return 1;}
Further understanding, you can look at the Tianyi Cui"backpack problem nine talk."
014-knapsack problem-dynamic programming-algorithmic design skills and analysis M.H.A study notes