单调队列优化多重背包
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;
}
}
}
而接下来要说的单调队列优化可以把复杂度降到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;
}
}
}
相关文章推荐
- 单调队列优化多重背包
- 单调队列优化的多重背包
- POJ 1742 Coins——不要套单调队列优化多重背包的模板
- POJ 1742 Coins 多重背包单调队列优化
- 背包模板(01,完全,多重背包的二进制优化和单调队列优化
- POJ 1742 Coins(多重背包 + 单调队列优化)
- 多重背包的优化 二进制/单调队列解析
- 多重背包单调队列优化
- 多重背包中多次背包 O(VN) 算法1 (单调队列优化) 带参考程序
- HDOJ 2191 (多重背包/二进制分解/单调队列优化DP)
- poj1742 单调队列优化多重背包
- 背包问题入门(单调队列优化多重背包
- 多重背包中多次背包 O(VN) 算法1 (单调队列优化) 带参考程序
- HDU 1171 Big Event in HDU (单调队列优化多重背包)
- bzoj1296 [SCOI2009]粉刷匠 分组背包/单调队列优化
- POJ 3260 The Fewest Coins(完全背包 + 多重背包 + 单调队列优化)
- 多重背包单调队列优化
- 单调队列优化多重背包(pascal及翻译过去的C代码)
- Dividing(多重背包、单调队列优化dp)
- poj 2373 单调队列优化背包