1.01 backpack
Two-dimensional recursive formula:
Code:
for (I=1 ; I<=n;i++" for (X=m;x>=1 ; X--) if (x>=w[i ]) F[i][x]=max (f[i-1 ][x-w[i]]+c[i],f[i-1 ][x]); else f[i][x]=f[i-1 ][x"; printf ( " %d ", F[n][m]); // F (n,m) is the optimal solution return 0 ;
Sometimes, however, a one-dimensional optimization can be considered when a two-dimensional array may be used because of the capacity or excessive number of items.
Using f[i] means that when I use the capacity of the maximum number of items can be loaded, we can introduce the following code:
for (int i=1; i<=n;i++) for (int j=m;j>0; j--) if (W[I]<=J) F[j]=max (f[j],f[j-w[i]]+c[i]);
And the above two code time complexity of the same, and the space complexity is much smaller, note that enumeration capacity J must be in reverse enumeration, the order enumeration may appear repeating the same article situation ... It's a full backpack.
Note that there are times when the restrictions on backpacks are sometimes more than one ... For example, outside of the weight, may add to the volume of additional restrictions, then we only need to add one more dimension. Dp[i][j] Represents the maximum value of using the weight of I, Volume J, the Code is as follows:
for (i=1; i<=n;i++) for (j=vv;j>=v[i];j--) for (k=gg;k>=g[i];k--) if (f[j][k]<f[j-v[i]][k-g[i]]+t[i]) f[j][k]=f[j-v[i]][k-g[i]]+t[i];
An example:
01 Backpack ideas, although the specific implementation may be a little different
You can use a two-dimensional array, dp[i][j], to get the first garbage (not yet decided whether to eat or heap), and J's health, at this time has reached the highest level, in order to ensure that the state of each enumeration exists. When I use two dimensions, I use the front to update the back ... It's different from the backpack: Dp[i][j]+h[i]=dp[i+1][j-w[i+1]],dp[i][j]=dp[i+1][j+f[i]-w[i+1]],w says it's time to wait when I get the bag of garbage. Pay attention to the conditions that need to be met when transferring (that is, J always >=0)
Code:
#include <iostream>#include<cstdio>#include<cstdlib>#include<cmath>#include<ctime>#include<cctype>#include<cstring>#include<string>#include<algorithm>using namespacestd;intd,g,dp[ the][3500];BOOLjud[ the][3500],flag=false;structnode{intT,f,h,w;} r[ the];inlineBOOLCMP (node A,node b) {returna.t<b.t;}intMain () {memset (DP,-127/3,sizeof(DP)); memset (Jud,false,sizeof(Jud)); dp[0][Ten]=0; jud[0][Ten]=true; scanf ("%d%d",&d,&g); for(intI=1; i<=g;i++) {scanf ("%d%d%d",&r[i].t,&r[i].f,&r[i].h); } sort (R+1, r+g+1, CMP); for(intI=1; i<=g;i++) {R[I].W=r[i].t-r[i-1].t; } for(intI=0; i<=g;i++) { for(intj=3200; j>=0; j--) { if(Jud[i][j]) {if(dp[i][j]+r[i].h>=d) {if(r[i].t==94) cout<<r[i+ at].t<<Endl; Elsecout<<r[i].t<<Endl; return 0; } if(j-r[i+1].w>=0) dp[i+1][j-r[i+1].w]=max (dp[i+1][j-r[i+1].w],dp[i][j]+r[i].h), jud[i+1][j-r[i+1].w]=true; if(j+r[i].f-r[i+1].w>=0) dp[i+1][j+r[i].f-r[i+1].w]=max (dp[i+1][j+r[i].f-r[i+1].W],DP[I][J]), jud[i+1][j+r[i].f-r[i+1].w]=true;//Note here the two if judgment}} } Loop:intk=Ten; for(intI=1; i<=g;i++) { if(k<r[i].t) {printf ("%d", K); return 0; } k=k+r[i].f; } printf ("%d", k);}
However, the 01 backpack with an array tends to be much smaller in code. And the idea is also more concise, we use dp[i] to express the height of the heap to I when the total maximum can live, for goods j,dp[h[j]+i]=max{dp[h[j]+i],dp[i]}, while Dp[i]+=f[j]
The code is as follows (reference yihan_z):
#include <cstdio>#include<algorithm>#defineMax (A, B) (A>B?A:B)using namespacestd;structgarbage{intE,h,t;//Energy,height,time BOOL operator< (ConstGarbage &x)Const{returnX.t>t;}} a[ the];intm,n,f[ the];intMain () {f[0]=Ten; scanf ("%d%d",&m,&N); for(intI=1; i<=n;i++) scanf ("%d%d%d",&a[i].t,&a[i].e,&a[i].h); Sort (a+1, A +1+N); for(intj=1; j<=n;j++) for(inti=m;i>=0; i--){ if(A[j].t>f[i])Continue; if(i+a[j].h>=m) {printf ("%d\n", a[j].t); return 0; } f[i+a[j].h]=max (f[i+A[j].h],f[i]); F[i]+=A[J].E; } printf ("%d\n", f[0]); return 0;}
2. Full Backpack:
Two-dimensional recursive formula:
Code:
for (int i=1; i<=n;i++) for (int j=1; j<=m;j++) { if(w[i]<=j) Dp[i][j]=max (dp[i-1][j],dp[i][j-w[i]]+c[ I]); Else dp[i][j]=dp[i-1][j]; }
The same can be done in one-dimensional optimization, just as mentioned in the above 01 backpack, this time will be enumerated in order:
for (int i=1;i<=n;i++) for (int j=1;j<=m;j++) if (W[I]<=J) F[j]=max (f[j],f[j-w[i]]+c[i]);
Examples show that I don't find much and are naked. Let's search on the internet ...
3. Multi-pack
Two-dimensional recursive formula:
Code:
int i=1; i<=n;i++) for (int j=1;j<=m;j++) { for (int k=0; k<=c[i];k++) if(j>=k* W[i]) Dp[i][j]=max (dp[i][j],dp[i-1][j-k*w[i]]+k*v[i]); DP[I][J]=max (dp[i][j],dp[i-1][j]); }
Multiple backpacks can also be easily optimized with one-dimensional, noting that the same as the 01 backpack is the reverse enumeration.
for (int i=1; i<=n;i++) for (int j=m;j>=1; j--) { for (int k=0; k<=c[i];k++) if(j>=k* W[i]) Dp[j]=max (dp[j],dp[j-w[i]*k]+v[i]*k); }
However, it is not difficult to find, in fact, the time complexity of multiple backpacks is much larger than the previous mentioned two backpack, in fact, for multiple backpacks and a way to optimize the time, will be in the future DP optimization mentioned
Finally, the question of a hybrid backpack:
Through analysis is not difficult to draw, this is a complete backpack + multi-backpack + two-dimensional cost of the knapsack problem, above these 3 cases have been told, now only use to mix it up ... The basis for the problem of knapsack is almost mastered ...
At the same time, this problem also fully embodies one-dimensional optimization of space superiority
#include <iostream>#include<cstdio>#include<cstdlib>#include<cmath>#include<ctime>#include<cctype>#include<cstring>#include<string>#include<algorithm>using namespacestd;Const intn=155;Const intm= the;intv[n],w1[n],w2[n],c[n],dp[m][m],n,m1,m2;intMain () {scanf ("%d%d%d",&n,&m1,&m2); for(intI=1; i<=n;i++) scanf ("%d%d%d%d",&w1[i],&w2[i],&c[i],&V[i]); for(intI=1; i<=n;i++) { if(!C[i]) for(intj=w1[i];j<=m1;j++) for(intk=w2[i];k<=m2;k++) Dp[j][k]=max (dp[j][k],dp[j-w1[i]][k-w2[i]]+V[i]); Else for(intj=m1;j>=w1[i];j--) for(intk=m2;k>=w2[i];k--) for(intL=0; l<=c[i];l++) if(j>=w1[i]*l&&k>=w2[i]*l) dp[j][k]=max (dp[j][k],dp[j-w1[i]*l][k-w2[i]*l]+v[i]*l); } cout<<dp[m1][m2]<<Endl; return 0;}
Finally, we summarize the problem of backpack DP class ... In fact, the knapsack problem is not complicated, fully familiar with the characteristics of each backpack, each analysis of the problem of the type of knapsack (such as above), and then with the corresponding ideas and code to
Algorithm review-Backpack DP