01背包+完全背包+多重背包+单调队列
Posted 钟钟终
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了01背包+完全背包+多重背包+单调队列相关的知识,希望对你有一定的参考价值。
01背包
代码:逆序更新
int n,m,f[105][N],dp[N];
void fun1()
for(int i=1;i<=n;i++) //物品i
for(int j=1;j<=m;j++) //容量j
if(j<w[i])
f[i][j]=f[i-1][j];
else
f[i][j]=max(f[i-1][j],f[i-1][j-w[i]]+c[i]);
cout<<f[n][m]<<endl;
void fun2() //逆序更新
for(int i=1;i<=n;i++)
for(int j=m;j>=w[i];j--)
dp[j]=max(dp[j],dp[j-w[i]]+c[i]);
完全背包
顺序更新
代码:
void fun1()
for(int i=1;i<=n;i++) //物品i
for(int j=1;j<=m;j++) //容量j
if(j<w[i])
f[i][j]=f[i-1][j];
else
f[i][j]=max(f[i-1][j],f[i][j-w[i]]+c[i]);
cout<<f[n][m]<<endl;
void fun2()
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<<dp[m]<<endl;
多重背包
朴素实现:
int n,v[N],w[N],f[N],s[N],vv[N],ww[N];
void fun1() //多重背包
for(int i=1;i<=n;i++) //物品种数
for(int j=m;j>=w[i];j--) //背包容量
for(int k=0;k<=s[i]&&k*v[i]<=j;k++)
f[j]=max(f[j],f[j-k*v[i]]+k*w[i]);
二进制优化
void fun2() //多重背包 二进制优化
int num=1;
for(int i=1;i<=n;i++)
int v,w,s; //体积、价值、数量
cin>>v>>w>>s;
for(int j=1;j<=s;j<<=1)
vv[num]=j*v;
ww[num++]=j*w;
s-=j;
if(s)
vv[num]=s*v,ww[num++]=s*w;
for(int i=1;i<num;i++)
for(int j=m;j>=vv[i];j--)
f[j]=max(f[j],f[j-vv[i]]+ww[i]);
cout<<f[m]<<endl;
单调队列
int n,a[N],q[N];
void solve()
int head=0,tail=-1;
for(int i=1;i<=n;i++)
if(head<=tail&&q[head]<i-m+1)
head++;
while(head<=tail&&a[i]>=a[q[tail]])
tail--;
q[++tail]=i;
if(i>=m) cout<<a[q[head]]<<" ";
cout<<endl;
以上是关于01背包+完全背包+多重背包+单调队列的主要内容,如果未能解决你的问题,请参考以下文章