Algorithm review-Backpack DP

Source: Internet
Author: User
Tags cmath

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&GT;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

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.