一、01背包模板
#include <bits/stdc++.h>
using namespace std;
int w[500],c[500],dp[500];
int v,n;
int main()
{
cin>>v>>n;
for(int i=1;i<=n;i++)
cin>>w[i]>>c[i];
for(int i=1;i<=n;i++)
for(int j=v;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
cout <<dp[v] << endl;
return 0;
}
二、完全背包
与01背包的区别是第二重循环是从w[i]开始,会重复
#include <bits/stdc++.h>
using namespace std;
int n,m,i,j,t,ans,tmp1,tmp2,w[101],c[35],dp[205];
int main()
{
ios::sync_with_stdio(false);
cin>>m>>n;
for(int i=1;i<=n;i++)cin>>w[i]>>c[i];
for(int i=1;i<=n;i++)
for(int j=w[i];j<=m;j++)
{
dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
}
cout<<"max="<<dp[m]<<endl;
return 0;
}
三、多重背包
有两种方法
1.直接增添一重循环,其它与01背包相同
#include <bits/stdc++.h>
using namespace std;
const int N=6e4+5;
int n,m,i,j,t,ans,tmp1,tmp2,w[N],c[N],dp[N],a[N];
int main()
{
ios::sync_with_stdio(false);
cin>>n>>m;
for(int i=1;i<=n;i++)cin>>w[i]>>c[i]>>a[i];
for(int i=1;i<=n;i++)
for(int k=1;k<=a[i];k++)
for(int j=m;j>=w[i];j--)
{
dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
}
cout<<dp[m]<<endl;
return 0;
}
2.二进制优化
这种方法可以节省时间
#include <bits/stdc++.h>
using namespace std;
int w[5001],c[5001],dp[5001];
int main()
{
int n,m;
int v,s,t,p=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
{
cin>>v>>t>>s;
int x=1;
while(s-x>0)
{
s=s-x;
w[++p]=x*v;
c[p]=x*t;
x=x*2;
}
w[++p]=s*v;
c[p]=s*t;
}
for(int i=1;i<=p;i++)
for(int j=m;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
cout<<dp[m]<<endl;
return 0;
}
四、混合背包
#include <bits/stdc++.h>
using namespace std;
const int N=1e6+5;
int rest,k,cnt,w0,c0,s,n,h1,h2,m1,m2,w[N],c[N],dp[N],a[N];
int main()
{
scanf("%d:%d %d:%d %d",&h1,&m1,&h2,&m2,&n);
int time=(h2-h1)*60+(m2-m1);
while(n--)
{
cin>>w0>>c0>>s;
if(s==0)
{
for(int j=w0;j<=time;j++)
dp[j]=max(dp[j],dp[j-w0]+c0);
}
else
{
rest=s;
k=1;
while(rest>=k)
{
w[++cnt]=w0*k;
c[cnt]=c0*k;
rest=rest-k;
k=k*2;
}
if(rest>0){w[++cnt]=w0*rest;c[cnt]=c0*rest;}
}
}
for(int i=1;i<=cnt;i++)
for(int j=time;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
cout<<dp[time]<<endl;
return 0;
}