背包(01,完全,多重,分组)
Posted zptcszj
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了背包(01,完全,多重,分组)相关的知识,希望对你有一定的参考价值。
01背包
#include <cstdio> #include <iostream> using namespace std; int main() { int m,n,dp[100005]; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { int w,p; scanf("%d%d",&w,&p); for(int j=m;j>=w;j--) { dp[j]=max(dp[j-w]+p,dp[j]); } } printf("%d ",dp[m]); return 0; }
完全背包
#include <cstdio> #include <iostream> using namespace std; int f[1005],v[1005],w[1005]; int main() { int n,m,ans; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) scanf("%d%d",&v[i],&w[i]); for(int i=1;i<=n;i++) { for(int j=v[i];j<=m;j++) { f[j]=max(f[j],f[j-v[i]]+w[i]); } } printf("%d ",f[m]); return 0; }
多重背包(优化)
#include <cstdio> #include <iostream> #include <vector> #include <algorithm> #include <cstring> using namespace std; int f[2005]; struct Good{ int v,w; }; vector <Good> goods; int main() { int n,m,ans,s,v,w; scanf("%d%d",&n,&m); for(int i=1;i<=n;i++) { scanf("%d%d%d",&v,&w,&s); for(int k=1;k<=s;k*=2) { s-=k; goods.push_back({v*k,w*k}); } if(s>0) goods.push_back({v*s,w*s}); } for(auto good:goods) { for(int j=m;j>=good.v;j--) { f[j]=max(f[j],f[j-good.v]+good.w); } } printf("%d ",f[m]); return 0; }
分组背包
#include <cstdio> #include <iostream> const int M=1010; using namespace std; int main() { int m,n,w[M],p[M],arr[110][M],ar[M],num=0,dp[M]; scanf("%d%d",&m,&n); for(int i=1;i<=n;i++) { int a; scanf("%d%d%d",&w[i],&p[i],&a); num=max(num,a); ar[a]++; arr[a][ar[a]]=i; } for(int i=1;i<=num;i++) { for(int j=0;j<=m;j++) { for(int k=1;k<=ar[i];k++) { int f=arr[i][k]; if(j+w[f]<=m) dp[j]=max(dp[j],dp[j+w[f]]+p[f]); } } } printf("%d ",dp[0]); return 0; }
混合背包
#include <cstdio> #include <iostream> #include <vector> #include <cstring> #include <algorithm> const int M=1010; using namespace std; struct Good{ int kind; int w,p; }; vector <Good> goods; int main() { int m,n,dp[M]; memset(dp,0,sizeof(dp)); cin>>n>>m; for(int i=0;i<n;i++) { int w,p,s; cin>>w>>p>>s; if(s<0) { goods.push_back({-1,w,p}); } else if(s==0) { goods.push_back({0,w,p}); } else { for(int k=1;k<=s;k*=2) { s-=k; goods.push_back({-1,w*k,p*k}); } if(s>0) goods.push_back({-1,w*s,p*s}); } } for(auto good:goods) { if(good.kind<0) { for(int j=m;j>=good.w;j--) dp[j]=max(dp[j],dp[j-good.w]+good.p); } else { for(int j=good.w;j<=m;j++) dp[j]=max(dp[j],dp[j-good.w]+good.p); } } cout<<dp[m]<<endl; return 0; }
以上是关于背包(01,完全,多重,分组)的主要内容,如果未能解决你的问题,请参考以下文章
背包整理(01背包,完全背包,多重背包,分组背包)(待更新)