2/17 01背包+完全背包+多重背包(二进制优化)+二位费用背包+dfs
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2/17 01背包+完全背包+多重背包(二进制优化)+二位费用背包+dfs相关的知识,希望对你有一定的参考价值。
多重背包(二进制优化) ------------------小吐槽:我还以为很难学呢,just so so~
https://www.luogu.com.cn/problem/P1833
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int h1,h2,m1,m2;
int n,w,ti[maxn],c[maxn],f[maxn],cnt;
int main()
scanf("%d:%d",&h1,&m1);scanf("%d:%d",&h2,&m2);
w=(h2-h1)*60-m1+m2;
scanf("%d",&n);
for(int i=1;i<=n;i++) //转化为01背包
int x,y,z;
scanf("%d%d%d",&x,&y,&z); //价值/重量/件数
if(!z)
z=999999;
int t=1;
while(z>=t)
ti[++cnt]=x*t;
c[cnt]=y*t;
z-=t;
t<<=1;
if(z)
ti[++cnt]=x*z;
c[cnt]=y*z;
for(int i=1;i<=cnt;i++)
for(int j=w;j>=ti[i];j--)
f[j]=max(f[j],f[j-ti[i]]+c[i]);
cout<<f[w]<<endl;
return 0;
https://www.luogu.com.cn/problem/P1776
#include <bits/stdc++.h>
using namespace std;
const int maxn=1e5+5;
int n,w,v[maxn],c[maxn],f[maxn];
int main()
int cnt=1;
scanf("%d%d",&n,&w);
for(int i=1;i<=n;i++) //转化为01背包
int x,y,z;scanf("%d%d%d",&x,&y,&z); //价值/重量/件数
int t=1;
while(z>=t)
v[cnt]=x*t;
c[cnt++]=y*t;
z-=t;
t<<=1;
if(z)
v[cnt]=x*z;
c[cnt++]=y*z;
cnt--;
for(int i=1;i<=cnt;i++)
for(int j=w;j>=c[i];j--)
f[j]=max(f[j],f[j-c[i]]+v[i]);
cout<<f[w]<<endl;
return 0;
经典深搜题:有助于理解深搜
https://www.luogu.com.cn/problem/P2066
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=20;
int n,m,a[maxn][maxn],f[maxn],ans[maxn],cnt;
void dfs(int id,int sum,int rest) //公司编号,利润,生育机器
if(rest<0) return;
if(id==n+1)
if(sum>cnt)
cnt=sum;
for(int i=1;i<=n;i++)
f[i]=ans[i];
return;
for(int i=0;i<=m;i++) //机器从0开始分配,有些公司可没有机器
ans[id]=i; //记录几台
dfs(id+1,sum+a[id][i],rest-i);
int main()
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
for(int j=1;j<=m;j++)
scanf("%d",&a[i][j]);
dfs(1,0,m);
cout<<cnt<<endl;
for(int i=1;i<=n;i++)
cout<<i<<" "<<f[i]<<endl;
return 0;
https://www.luogu.com.cn/problem/P1509
二维费用背包:
附加要求:约到数量最多的女孩,还要花的钱最少的时间
开两个二维数组分别记录
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=105;
int n,m,r,rmp[maxn],rp[maxn],f1[maxn][maxn],f2[maxn][maxn];
int ti[maxn];
int main()
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d%d",&rmp[i],&rp[i],&ti[i]);
scanf("%d%d",&m,&r);
for(int i=1;i<=n;i++)
for(int v=m;v>=rmp[i];v--)
for(int u=r;u>=rp[i];u--)
int n1=f1[v][u];
int n2=f1[v-rmp[i]][u-rp[i]]+1; //约到女孩的数量
int t1=f2[v-rmp[i]][u-rp[i]]+ti[i]; //约到女孩花的时间
f1[v][u]=max(n1,n2);
if(n1==n2) //若数量相等取时间少的
f2[v][u]=min(f2[v][u],t1);
else if(n2>n1) //数量多的优先,记录时间
f2[v][u]=t1;
int ans=inf;
for(int i=1;i<=m;i++)
for(int j=1;j<=r;j++)
if(f1[m][r]==f1[i][j])
ans=min(ans,f2[i][j]);
cout<<ans<<endl;
return 0;
https://www.luogu.com.cn/problem/P1853
完全背包:
注意不断更新s的值
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e8+5;
int s,n,d,a[50],b[50],f[maxn];
int main()
scanf("%d%d%d",&s,&n,&d);
for(int i=1;i<=d;i++)
scanf("%d%d",&a[i],&b[i]);
for(int i=1;i<=n;i++) //年数
for(int j=1;j<=d;j++) //债券的完全背包
for(int k=a[j];k<=s;k++)
f[k]=max(f[k],f[k-a[j]]+b[j]);
s+=f[s]; //加上每年的利息f[s]
cout<<s<<endl;
return 0;
https://www.luogu.com.cn/problem/P2370
01背包+快排(根据题意)
注:虽然01背包队物品排列并不关心,但根据排序是非常必要的
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1005;
int n,p,s,dp[maxn],ans=inf,tmp;
struct node
int a,b;
e[maxn];
bool cmp(node e1,node e2)
return e1.a<e2.a;
int main()
scanf("%d%d%d",&n,&p,&s);
for(int i=1;i<=n;i++)
scanf("%d%d",&e[i].a,&e[i].b);
sort(e+1,e+n+1,cmp);
for(int i=1;i<=n;i++)
for(int j=s;j>=e[i].a;j--)
dp[j]=max(dp[j],dp[j-e[i].a]+e[i].b);
if(dp[j]>=p)
cout<<e[i].a<<endl;
return 0;
cout<<"No Solution!"<<endl;
return 0;
https://www.luogu.com.cn/problem/P2725
完全背包吧所有情况都罗列出来,如果需要的邮票数还是初始化的inf,则上一个数字就是答案
#include <bits/stdc++.h>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=1e7+5;
int k,n,f[maxn],ans;
int main()
scanf("%d%d",&k,&n);
memset(f,inf,sizeof(f));
f[0]=0;
for(int i=1;i<=n;i++)
int x;scanf("%d",&x);
for(int j=x;j<=maxn;j++)
if(f[j-x]+1<=k)
f[j]=min(f[j],f[j-x]+1);
for(int i=1;i<=maxn;i++)
if(f[i]==inf)
ans=i-1;break;
cout<<ans<<endl;
return 0;
以上是关于2/17 01背包+完全背包+多重背包(二进制优化)+二位费用背包+dfs的主要内容,如果未能解决你的问题,请参考以下文章