背包
记录一下背包的各种模板
① 01背包
题目链接:https://www.acwing.com/problem/content/2/
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stack> #include <queue> #include <cmath> #define ll long long #define pi 3.1415927 #define inf 0x3f3f3f3f using namespace std; int dp[1005]; int main () { int n,m,i,t,j,k,v,v1,w; cin>>n>>v; for(i=1;i<=n;++i) { cin>>v1>>w; for(t=v;t>=v1;--t) dp[t]=max(w+dp[t-v1],dp[t]); } cout<<dp[v]<<endl; return 0; }
②完全背包
题目链接:https://www.acwing.com/problem/content/3/
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stack> #include <queue> #include <cmath> #define ll long long #define pi 3.1415927 #define inf 0x3f3f3f3f using namespace std; int dp[1005]; int main () { int n,m,i,t,j,k,v,v1,w; cin>>n>>v; for(i=1;i<=n;++i) { cin>>v1>>w; for(t=v1;t<=v;++t) dp[t]=max(w+dp[t-v1],dp[t]); } cout<<dp[v]<<endl; return 0; }
③多重背包Ⅰ
题目链接:https://www.acwing.com/problem/content/4/
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stack> #include <queue> #include <cmath> #define ll long long #define pi 3.1415927 #define inf 0x3f3f3f3f using namespace std; int dp[1005]; int main () { int n,m,i,t,j,k,v,v1,w; cin>>n>>v; for(i=1;i<=n;++i) { cin>>v1>>w>>j; for(t=v;t>=v1;--t) for(k=1;k<=j&&k*v1<=t;++k) dp[t]=max(k*w+dp[t-k*v1],dp[t]); } cout<<dp[v]<<endl; return 0; }
④多重背包Ⅱ
题目链接:https://www.acwing.com/problem/content/5/
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stack> #include <queue> #include <cmath> #include <vector> #define ll long long #define pi 3.1415927 #define inf 0x3f3f3f3f using namespace std; int dp[2005]; struct node { int v,w; }; vector<node> pp; int main () { int n,m,i,t,j,k,v,v1,w,p; cin>>n>>v; for(i=1;i<=n;++i) { cin>>v1>>w>>j; for(t=1;t<=j;t<<=1){ pp.push_back({t*v1,t*w}); j-=t; } if(j>0) pp.push_back({j*v1,j*w}); } m=pp.size(); for(int h=0;h<m;++h) for(t=v;t>=pp[h].v;--t) dp[t]=max(pp[h].w+dp[t-pp[h].v],dp[t]); cout<<dp[v]<<endl; return 0; }
⑤多重背包Ⅲ
题目链接:https://www.acwing.com/problem/content/6/
代码待补_(:з)∠)_
⑥混合背包
题目链接:https://www.acwing.com/problem/content/7/
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stack> #include <queue> #include <vector> #include <cmath> #define ll long long #define pi 3.1415927 #define inf 0x3f3f3f3f using namespace std; int dp[1005]; struct node { int s,v,w; }; vector<node> pp; int main () { int n,m,i,t,j,k,v1,w,s1,v; cin>>n>>v; for(i=0;i<n;++i) { cin>>v1>>w>>s1; if(s1<=0) pp.push_back({s1,v1,w}); else { for(j=1;j<=s1;j<<=1) { pp.push_back({1,j*v1,j*w}); s1-=j; } if(s1) pp.push_back({1,s1*v1,s1*w}); } } m=pp.size(); for(i=0;i<m;++i) { if(pp[i].s==0) { for(j=pp[i].v;j<=v;++j) dp[j]=max(dp[j],dp[j-pp[i].v]+pp[i].w); } else { for(j=v;j>=pp[i].v;--j) dp[j]=max(dp[j],dp[j-pp[i].v]+pp[i].w); } } cout<<dp[v]<<endl; return 0; }
⑦二维费用的背包问题
题目链接:https://www.acwing.com/problem/content/8/
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stack> #include <queue> #include <cmath> #define ll long long #define pi 3.1415927 #define inf 0x3f3f3f3f using namespace std; int dp[1005][1005]; int main () { int n,m,i,t,j,k,v,v1,m1,w; cin>>n>>v>>m; while(n--) { cin>>v1>>m1>>w; for(i=v;i>=v1;--i) for(j=m;j>=m1;--j) dp[i][j]=max(dp[i][j],w+dp[i-v1][j-m1]); } cout<<dp[v][m]<<endl; return 0; }
⑧分组背包
题目链接: https://www.acwing.com/problem/content/9/
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stack> #include <queue> #include <cmath> #define ll long long #define pi 3.1415927 #define inf 0x3f3f3f3f using namespace std; int dp[1005],v1[105],w[105]; int main () { int n,m,i,t,j,k,v,s; cin>>n>>v; while(n--) { cin>>s; for(i=1;i<=s;++i) cin>>v1[i]>>w[i]; for(t=v;t>=0;--t) for(i=1;i<=s;++i) if(t>=v1[i]) dp[t]=max(dp[t],dp[t-v1[i]]+w[i]); } cout<<dp[v]<<endl; return 0; }
⑨有依赖的背包
链接:https://www.acwing.com/problem/content/10/
待补
⑩背包问题求方案数
链接:https://www.acwing.com/problem/content/11/
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stack> #include <queue> #include <cmath> #define ll long long #define pi 3.1415927 #define inf 0x3f3f3f3f #define mod 1000000007 using namespace std; int dp[1005],res[1005]; int main () { int n,m,i,t,j,k,v,v1,w; cin>>n>>v; res[0]=1; while(n--) { cin>>v1>>w; for(i=v;i>=v1;--i) if(dp[i]<dp[i-v1]+w) { dp[i]=dp[i-v1]+w; res[i]=res[i-v1]; } else if(dp[i]==dp[i-v1]+w) { res[i]=res[i]+res[i-v1]; res[i]%=mod; } } int maxs=-1; for(i=0;i<=v;++i) //cout<<dp[i]<<endl; maxs=max(maxs,dp[i]); int sum=0; for(i=0;i<=v;++i) if(maxs==dp[i]) sum+=res[i]; cout<<sum<<endl; return 0; }
11 背包问题求具体方案
题目链接:https://www.acwing.com/problem/content/12/
#include <cstdio> #include <iostream> #include <algorithm> #include <cstring> #include <string> #include <stack> #include <queue> #include <cmath> #define ll long long #define pi 3.1415927 #define inf 0x3f3f3f3f using namespace std; int dp[1005][1005]; int v1[1005],w[1005]; int main () { int n,m,i,t,j,k,v; cin>>n>>v; for(i=1;i<=n;++i) cin>>v1[i]>>w[i]; for(i=n;i>=1;--i) for(t=0;t<=v;++t) { if(t>=v1[i]) dp[i][t]=max(dp[i+1][t],dp[i+1][t-v1[i]]+w[i]); else dp[i][t]=dp[i+1][t]; } int temp=v; for(i=1;i<=n;++i) { if(temp>=v1[i] && dp[i][temp]==dp[i+1][temp-v1[i]]+w[i] ) { cout<<i<<" "; temp-=v1[i]; } } cout<<endl; return 0; }