背包
目录
P1048 [NOIP2005 普及组] 采药(01背包):
#include<bits/stdc++.h>
using namespace std;
int m,bag,dp[100005],t,w;
int main()
{
scanf("%d%d",&bag,&m);
for(int i = 1;i<=m;i++)
{
scanf("%d%d",&t,&w);
for(int j = bag;j>=t;--j)
dp[j]=max(dp[j],dp[j-t]+w);
}
printf("%d",dp[bag]);
return 0;
}
P1616 疯狂的采药(完全背包):
#include<iostream>
#include<cmath>
using namespace std;
long long int n,v,f[10000000],c[10000000],w[100000000],k;
int main()
{
cin>>v>>n;
for(int i=1;i<=n;i++) cin>>c[i]>>w[i];
for(int i=1;i<=n;i++)
for(int j=c[i];j<=v;j++)
f[j]=max(f[j],f[j-c[i]]+w[i]);
cout<<f[v];
return 0;
}
多重背包 P1776 宝物筛选(倍增(?)优化)
#include<bits/stdc++.h>
#define for1(i,a,b) for(register ll i = a;i<=b;i++)
#define ll long long
using namespace std;
ll n,t,v,f[10000007],c[500005],w[500005],num[500005],ans;
int main()
{
scanf("%lld%lld",&n,&v);
for1(i,1,n) scanf("%lld%lld%lld",&w[i],&c[i],&num[i]);
for1(i,1,n)
{
ll mx=min(v/c[i],num[i]);
for(ll k = 1;mx>0;k*=2)
{
if(k>mx) k=mx;
for(int j = v;j>=c[i]*k;j--)
{
f[j]=max(f[j],f[j-c[i]*k]+w[i]*k);
}
mx-=k;
}
}
printf("%lld",f[v]);
return 0;
}
多重背包 P1776 宝物筛选(单调队列优化)
#include<bits/stdc++.h>
#define for1(i,a,b) for(int i = a;i<=b;i++)
using namespace std;
int head,dl[500005],tail,n,m,w,v,num,dp[500005],ji[500005];//ji记录上一次循环时的dp数组
int main()
{
scanf("%d%d",&n,&m);
for1(i,1,n)
{
scanf("%d %d %d",&v,&w,&num);
for1(i,1,m)
ji[i]=dp[i];
for1(j,0,w-1)//j表示余数
{
head=1,tail=0;
for(int k=j;k<=m;k+=w)
{
if(tail>=head&&(k-dl[head])/w>num)head++;//要保证加入物品后,队列的头选取的数量要小于等于s,如果大于s那就越界了.
//保证加入当前物品后,编号(体积)在给定的窗口之中,(k-dl[head]/v就是要加入物品的数量
while(tail>=head&&(dl[tail]-k)/w*v+ji[k]>=ji[dl[tail]]) tail--;// 比较当前将要加入队列的元素和单调队尾相比,不单调就删队尾
if(tail>=head)dp[k]=max(dp[k],ji[dl[head]]+(k-dl[head])/w*v);//更新
dl[++tail]=k;//入队
}
}
}
cout<<dp[m]<<endl;
return 0;
}
混合背包 P1833 樱花
#include<bits/stdc++.h>
#define for1(i,a,b) for(int i =a;i<=b;i++)
using namespace std;
int c,n,w,p,v[1000005],f[1000005],num[1000005],mx,ji;
int main()
{
int nx,ny,ex,ey,n;
scanf("%d:%d%d:%d%d",&nx,&ny,&ex,&ey,&n);
int V=(ex*60+ey)-(nx*60+ny);
for (int i = 1; i <= n; i++)
{
cin >> c >> w >> p;
if (p == 0)
for (int j = c; j <= V; j++)
f[j] = max(f[j], f[j - c] + w);
else if (p == -1)
for (int j = V; j >= c; j--)
f[j] = max(f[j], f[j - c] + w);
else {
int num = min(p, V / c);
for (int k = 1; num > 0; k <<= 1)
{
if (k > num) k = num;
num -= k;
for (int j = V; j >= c * k; j--)
f[j] = max(f[j], f[j - c * k] + w * k);
}
}
}
cout<<f[V];
return 0;
}
二维费用背包P1507 NASA的食物计划
#include<bits/stdc++.h>
#define for1(i,a,b) for(register ll i = a;i<=b;i++)
#define ll long long
using namespace std;
ll n,t,v,f[1007][900],c2[500005],c[500005],w[500005],num[500005],ans;
ll m;
int main()
{
scanf("%lld%lld",&v,&m);
cin>>n;
for1(i,1,n) scanf("%lld%lld%lld",&c[i],&c2[i],&w[i]);
for1(i,1,n)
for(int j = v;j>=c[i];j--)
for(int k = m;k>=c2[i];k--)
f[j][k]=max(f[j][k],f[j-c[i]][k-c2[i]]+w[i]);
printf("%lld",f[v][m]);
return 0;
}
分组背包P1757 通天之分组背包
#include<bits/stdc++.h>
#define for1(i,a,b) for(register ll i = a;i<=b;i++)
#define ll long long
#define mp(a,b) make_pair(a,b)
using namespace std;
ll n,t,v,f[5007],ji[2001][2001],c[5005],w[5005],num[5005],ans;
int main()
{
ll x;
scanf("%lld%lld",&v,&n);
for1(i,1,n) scanf("%lld%lld%lld",&c[i],&w[i],&x),t=max(x,t),num[x]++,ji[x][num[x]]=i;
for(int i = 1;i<=t;i++)
{
for(int j = v;j>=0;j--)
for(int k = 1;k<=num[i];k++)
if(j>=c[ji[i][k]])
f[j]=max(f[j],f[j-c[ji[i][k]]]+w[ji[i][k]]);
}
printf("%lld",f[v]);
return 0;
}
有依赖的背包P1064 [NOIP2006 提高组] 金明的预算方案
#include<bits/stdc++.h>
using namespace std;
int n,v,f[200005],c[200005],w[200005],vis[200005];
vector < int > fj[200005];
int main()
{
cin>>v>>n;
int x,y,z;
for(int i=1;i<=n;i++)
{
scanf("%d%d%d",&x,&y,&z);
w[i]=x*y;
c[i]=x;
if(z!=0) fj[z].push_back(i),vis[i]=1;
}
for(int i=1;i<=n;i++)
{
if(vis[i]==0)
{
for(int j=v;j>=c[i];j--)
{
f[j]=max(f[j],f[j-c[i]]+w[i]);
if(fj[i].size()==1)
{
if(j>=c[i]+c[fj[i][0]])
f[j]=max(f[j],f[j-c[i]-c[fj[i][0]]]+w[i]+w[fj[i][0]]);
}
if(fj[i].size()==2)
{
if(j>=c[i]+c[fj[i][0]])
f[j]=max(f[j],f[j-c[i]-c[fj[i][0]]]+w[i]+w[fj[i][0]]);
if(j>=c[i]+c[fj[i][1]])
f[j]=max(f[j],f[j-c[i]-c[fj[i][1]]]+w[i]+w[fj[i][1]]);
if(j>=c[i]+c[fj[i][0]]+c[fj[i][1]])
f[j]=max(f[j],f[j-c[i]-c[fj[i][1]]-c[fj[i][0]]]+w[i]+w[fj[i][0]]+w[fj[i][1]]);
}
}
}
}
cout<<f[v];
}

浙公网安备 33010602011771号