多重背包问题:

  有n件物品,第i件价值为wi,质量为vi,有c1件,问,给定容量V,求获得的最大价值。

  

朴素做法:

  视为0,1,2,...,k种物品的分组背包 [每组只能选一个]

  f[i][j]=Max(f[i][j-k*v[i]]+k*w[i])

  但是i,j,k都要枚举,复杂度为 n*V*k

朴素做法的改进:

  因为发现用二进制可以表示1..k之内的所有数 [整数二进制打开后为01串,所以可以被二进制表示]

  所以将k个物品拆分成1,2,4...2^m,k-2^m   ( 其中2^m<=k<2^(m+1) ) 这些物品,然后变成01背包问题。

  但是n的数目增多了,复杂度为 n*V*logk

利用单调队列的改进:

  1.我们可以发现每个容量都能表示成 v*x+d 的形式[ v表示当前考虑的物品的容量 ]

  2.在上一点的启发下,我们发现一个f[v*x+d]在考虑当前物品时,只能由f[v*y+d]转移而来。 [其中x-y<=k]。

  也就是说,对v取模的余数相同的容量之间才能互相转移,而且要求x-y<=k。又因为求的是最大值的转移,所以满足单调队列的适用性。

  于是乎,我们对于余数d相同的容量分别建一个单调队列,然后枚举x f[x*v+d],进行转移即可。

  

 #include<cstdio>
#include<cstring> inline int in(){
int x=,flag=;char ch=getchar();
while(ch!='-' && (ch>'' || ch<'')) ch=getchar();
if(ch=='-') flag=-,ch=getchar();
while(ch>='' && ch<='') x=x*+ch-'',ch=getchar();
return x*flag;
} int a[],b[],f[];
int w,v,k,n,V,l,r; void insert(int x,int y){
while(l<=r && b[r]<=y) r--;
a[++r]=x; b[r]=y;
} inline int Max(int a,int b){
if(a>b) return a;return b;
} int main(){
n=in(),V=in();
int Lim;
for(int i=;i<=n;i++){
v=in();w=in();k=in();
if(k==){
for(int j=V;j>=v;j--)
f[j]=Max(f[j],f[j-v]+w);
continue;
}
else if(k<){
for(int j=v;j<=V;j++)
f[j]=Max(f[j],f[j-v]+w);
continue;
}
if(V/v<k) k=V/v;
for(int d=;d<v;d++){
l=,r=;Lim=(V-d)/v;
for(int x=;x<=Lim;x++){
insert(x,f[x*v+d]-x*w);
if(a[l]<x-k) l++;
f[x*v+d]=b[l]+x*w;
}
}
}
printf("%d",f[V]);
return ;
}

codevs 3269 混合背包

AC通道:http://codevs.cn/problem/3269/

O(V*n)的多重背包问题的更多相关文章

  1. 多重背包问题:悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(HDU 2191)(二进制优化)

    悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 HDU 2191 一道裸的多重背包问题: #include<iostream> #include<algorithm> #i ...

  2. 多重背包问题的两种O(M*N)解法

    多重背包的题目很多,最著名的是poj1742楼教主的男人八题之一. poj1742:coins 有几种面值的钱币和每种的数量,问能够组成m以内的多少种钱数 这个题大家都归为多重背包问题,不过跟实际意义 ...

  3. 5. 多重背包问题 II 【用二进制优化】

    多重背包问题 II 描述 有 NN 种物品和一个容量是 VV 的背包. 第 ii 种物品最多有 sisi 件,每件体积是 vivi,价值是 wiwi. 求解将哪些物品装入背包,可使物品体积总和不超过背 ...

  4. 4. 多重背包问题 I

    多重背包问题 I 描述 有 NN 种物品和一个容量是 VV 的背包. 第 ii 种物品最多有 sisi 件,每件体积是 vivi,价值是 wiwi. 求解将哪些物品装入背包,可使物品体积总和不超过背包 ...

  5. 51nod 多重背包问题(动态规划)

    多重背包问题 一个背包,承量有限为W,有n种物体,第i种物体,价值Vi,占用重量为 Wi,且有Ci件,选择物品若干放入背包,使得总重量不超过背包的承重.总价值最大? 输入 第1行,2个整数,N和W中间 ...

  6. C语言-多重背包问题

    多重背包问题 问题:有N种物品和一个容量为V的背包.第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i].求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大. 分 ...

  7. 多重背包问题II

    多重背包问题II 总体积是m,每个小物品的体积是A[i] ,每个小物品的数量是B[i],每个小物品的价值是C[i] 求能够放入背包内的最大物品能够获得的最大价值 和上一个很类似 上一题体积就是价值,这 ...

  8. 【动态规划/多重背包问题】POJ1014-Dividing

    多重背包问题的优化版来做,详见之前的动态规划读书笔记. dp[i][j]表示前i中数加得到j时第i种数最多剩余几个(不能加和得到i的情况下为-1)递推式为: dp[i][j]=mi(dp[i-1][j ...

  9. poj 1742 多重背包问题 dp算法

    题意:硬币分别有 A1.....An种,每种各有C1......Cn个,问组成小于m的有多少种 思路:多重背包问题 dp[i][j]表示用前i种硬币组成j最多剩下多少个  dp=-1的表示凑不齐 dp ...

随机推荐

  1. Outlook 2007无法打开链接"由于本机的限制 该操作已被取消"

    编写人:CC阿爸 2014-2-17 近来在日常维护中,经常性的遇到用户在outlook中打开链接,提示[由于本机的限制,该操作已被取消],第一次的在网上搜索到解决办法后, 第二次再处理时,又没能记住 ...

  2. 使用DBCP时发生AbstractMethodError异常

    使用DBCP时发生AbstractMethodError异常,错误描述: Exception in thread "main" java.lang.AbstractMethodEr ...

  3. PHP MYSQLI中事务处理

    MYSQL事务处理让所有sql语句执行成功后才去处理,如果有一条没有成功或者报错就会回滚事务,防止敏感操作处理失败.MYSQL中只有INNODB和BDB类型的数据表才能支持事务处理!其它类型是不支持的 ...

  4. Java transient volatile关键字(转)

    Volatile修饰的成员变量在每次被线程访问时,都强迫从主内存中重读该成员变量的值.而且,当成员变量发生变化时,强迫线程将变化值回写到主内存.这样在任何时刻,两个不同的线程总是看到某个成员变量的同一 ...

  5. Java找出所有的水仙花数并输出

    水仙花数是三位数,它的各位数字的立方和等于这个三位数本身,例如:371=33+73+13,371就是一个水仙花数. 要判断是否是水仙花数,首先得得到它的每一位上的数.个位数即为对10取余:十位数为对1 ...

  6. Firebird 修改表名

    UPDATE RDB$RELATIONS SET  RDB$RELATION_NAME='NEWNAME' where RDB$RELATION_NAME='OLDNAME'; UPDATE RDB$ ...

  7. 从客户端检测到有潜在危险的Request.Form 值【转】

    asp.net开发中,经常遇到“从客户端检测到有潜在危险的Request.Form 值”错误提示,很多人给出的解决方案是: 1.web.config文档<system.web>后面加入这一 ...

  8. ok6410串口裸机总结

    1.串口角色:(1)数据传输通道(2)控制台 2.通讯参数(1)波特率:衡量传输速率的快慢,每秒钟传输数据的位数(bit)(2)数据位:有效数据(3)起始位:线路空闲的时候是高电平,当检测到低电平认为 ...

  9. Linux下使用Magent+Memcached缓存服务器集群部署

    1.编译安装libevent  cd /root/soft_hhf/  wget http://cloud.github.com/downloads/libevent/libevent/libeven ...

  10. swift学习初步(三)--控制流操作

    在上一篇博客里面,我谈到了swift里面的一些基本类型以及相关的操作,相信你看了之后一定会觉得其实swift也不难嘛.好吧,这篇博客里面要谈的一些高级操作,可能会让你有点头疼了. 好了,废话不多说了, ...