多重背包 2016.5.8

一、题目

有N种物品和一个容量为V 的背包

第i种物品最多有 Mi 件可用,每件耗费的空间是Ci,价值是W

求解将哪些物品装入背包可使这些物品的耗费的空间总和不超过背包容量,且价值总和最大

二、基本算法

这题目和完全背包问题很类似

基本的方程只需将完全背包问题的方程略微一改即可

因为对于第 i 种物品有 Mi+1 种策略:

取0件,取1件……取Mi件

令 dp[i, v]表示前 i 种物品恰放入一个容量为v的背包的最大价值,则有状态转移方程:

dp[i, v] = max{dp[i ? 1, v ? k ? Ci] + k ? Wi | 0 ≤ k ≤ Mi}

复杂度是O(V * ΣMi)

3、转化为01背包问题

另一种好想好写的基本方法是转化为01背包求解:

把第i种物品换成 Mi 件01背包中的物品,则得到了物品数为 ΣMi 的01背包问题

直接求解之,复杂度仍然是O(V * ΣMi)

但是我们期望将它转化为01背包问题之后,能够像完全背包一样降低复杂度

仍然考虑二进制的思想,我们考虑把第i种物品换成若干件物品

使得原问题中第i种物品可取的每种策略——取 0...Mi 件——均能等价于取若干件代换以后的物品

另外,取超过Mi件的策略必不能出现

方法是:

将第 i 种物品分成若干件01背包中的物品,其中每件物品有一个系数

这件物品的费用和价值均是原来的费用和价值乘以这个系数

令这些系数分别为1,  2,  2^2  ... 2^(k?1),  Mi ? 2^k + 1,且 k 是满足 Mi ? 2^k + 1 > 0 的最大整数

例如,如果Mi为13,则相应的k = 3,这种最多取13件的物品应被分成系数分别为1, 2, 4, 6的四件物品

分成的这几件物品的系数和为 Mi,表明不可能取多于 Mi 件的第i种物品

另外这种方法也能保证对于0...Mi间的每一个整数,均可以用若干个系数的和表示

这里算法正确性的证明可以分0... 2k?1和2k ...Mi两段来分别讨论得出

这样就将第i种物品分成了 O(logMi) 种物品,将原问题转化为了复杂度为 O(V ΣlogMi) 的01背包问题,是很大的改进

下面给出O(logM)时间处理一件多重背包中物品的过程:

def MultiplePack(dp, C, W ,M)

if C · M ≥ V

CompletePack(dp, C, W )

return

k := 1

while k < M

ZeroOnePack(kC, kW)

M := M ? k

k := 2k

ZeroOnePack(C · M, W · M)

四、O(V * N)算法

多重背包问题同样有O(V N)复杂度的算法

这个算法基于基本算法的状态转移方程

但应用单调队列的方法使每个状态的值可以以均摊O(1)的时间求解

这个方法在楼天成的“男人八题”幻灯片上

单调队列的讲解:

五、小结

在这一讲中,我们看到了将一个算法的复杂度由O(V ΣMi)改进到O(V ΣlogMi)的过程

还知道了存在复杂度为O(V N)的算法

要特别注意“拆分物品”的思想和方法,自己证明一下它的正确性,并将完整的程序代码写出来

转自《背包九讲V_2.0》%%%作者,感谢作者

时间: 2024-10-08 10:21:22

多重背包 2016.5.8的相关文章

[hdu5445 Food Problem]多重背包

题意:一堆食物,有价值.空间.数量三种属性,一些卡车,有空间,价格,数量三种属性.求最少的钱(不超过50000)买卡车装下价值大于等于给定价值的食物,食物可以拆开来放. 思路:这题的关键是给定的条件:食物可以拆开来放.这个条件使得卡车和食物可以分开考虑,然后通过空间这个属性联系在一起.做两遍多重背包即可. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35

hdu 2079 选课时间(题目已修改,注意读题) 多重背包

选课时间(题目已修改,注意读题) Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 3162    Accepted Submission(s): 2472 Problem Description 又到了选课的时间了,xhd看着选课表发呆,为了想让下一学期好过点,他想知道学n个学分共有多少组合.你来帮帮他吧.(xhd认为一样学分的课没区别

HDU-1171 Big Event in HDU (多重背包)

Problem Description Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don't know that Computer College had ever been split into Computer College and Software College in 2002.The splitting is absolutely a big

Holding Bin-Laden Captive!(1.多重背包 2.母函数)

Holding Bin-Laden Captive! Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 41 Accepted Submission(s): 29   Problem Description We all know that Bin-Laden is a notorious terrorist, and he has disap

HDU1171--Big Event in HDU(多重背包)

Big Event in HDU   Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 1139 Accepted Submission(s): 444 Problem Description Nowadays, we all know that Computer College is the biggest department in HD

HDU5677 manacher + 二维多重背包

附上题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5677 问题描述 ztr喜欢研究子串,今天,他有n个串 现在ztr想知道,能否从这n个串的所有回文子串中, 取出恰好k个回文串且满足这些回文串的长度之和为L 以yjqqaq为例 这个串包含的回文子串有 y,j,q,a,q,qq,qaq 所以我们可以既选qq,又选qaq 输入描述 有T组数据,第一行为一个正整数T(T<=10)T(T<=10) 每组数据第一行为三个正整数N(1<=N<

HDU 2191 多重背包

悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 22865    Accepted Submission(s): 9661 Problem Description 急!灾区的食物依然短缺!为了挽救灾区同胞的生命,心系灾区同胞的你准备自己采购一些粮食支援灾区,现在假设你一共有资金n元,而市

dp背包问题/01背包,完全背包,多重背包,/coin change算法求花硬币的种类数

一步一步循序渐进. Coin Change 具体思想:给你 N元,然后你有几种零钱S={S1,S2...,Sm} (每种零钱数量不限). 问:凑成N有多少种组合方式  即N=x1 * S1+x2*S2+...+xk*Sk (xk>=0,k=1,2..m) 设有f(x)中组合方式 有两种解答(自底向上回溯): 1.不用第m种货币   f(N,m-1) 2.用第m种货币 f(N-Sm,m) 总的组合方式为f(N,m)=f(N,m-1)+f(N-Sm,m) anything is nonsense,s

hdu 1059 (多重背包) Dividing

这里;http://acm.hdu.edu.cn/showproblem.php?pid=1059 题意是有价值分别为1,2,3,4,5,6的商品各若干个,给出每种商品的数量,问是否能够分成价值相等的两份. 联想到多重背包,稍微用二进制优化一下.(最近身体不适,压力山大啊) 1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #define inf 70000 5 using namespace s