您的位置:首页 > 其它

单调队列优化多重背包

2017-09-05 20:34 218 查看
前面写的二进制优化多重背包可以把复杂度降到O(m*∑log k[i])

而接下来要说的单调队列优化可以把复杂度降到O(n*m);

我们知道,单调队列优化的条件是dp方程可以转移成如下形式

dp[i]=max/min(f[k])+g[i]     (k<i  且g[i]与k无关)

而在多重背包中,如果把当前体积m分成v组(0,1,2,3,……v-1)
就可以得到方程f[i*v+x]=f[k*v+x]+(i-k)*w;

即dp[i]=dp[k]+(i-k)*w;

dp[i]=dp[k]-k*w+i*w;

显然可以使用单调队列来进行优化

下面是代码实现

scanf("%d%d",&n,&m);//物品数,包体积
for(i=0;i<n;i++){
scanf("%d%d%d",&v,&w,&num);//当前物品的参数
if(m/c<num)//小优化,防止溢出而进行多余的运算
num=m/c;
for(k=0;k<v;k++){
head=tail=0;
for(j=0;j<(m-k)/c;j++){
int x=j;
int y=f[j*v+k]-j*w;
while(head<tail && y>=b[tail-1])
tail--;
a[tail]=x;//下标
b[tail++]=y;//值
while(a[head]<j-num)
head++;
f[j*v+k]=b[head]+j*w;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: