题意简述
(按洛谷,HDU的输入顺序略有不同,还多组数据,较为毒瘤)
多重背包问题。给n,m,分别表示物品数量,背包总容积,每个物品依次给出3个属性w,v,c,表示物品的价值,重量,能选多少个。请在背包不爆炸的情况下选价值最大。
数据
输入:
4 20
3 9 3
5 9 1
9 4 2
8 1 3
输出:
47
思路
在朴素的多重背包中,我们设 f [ i ] [ j ] f[i][j] f[i][j]为考虑前 i i i个物品,然后背包容量为 j j j时的最优解。显然有 f [ i ] [ j ] = m a x { f [ i − 1 ] [ j − k ∗ v [ i ] ] + k ∗ w [ i ] } f[i][j]=max\{ f[i-1][j-k*v[i]]+k*w[i]\} f[i][j]=max{ f[i−1][j−k∗v[i]]+k∗w[i]},其中 0 < = k < = m i n { c [ i ] , m / v [ i ] } 0<=k<=min\{c[i],m/v[i]\} 0<=k<=min{ c[i],m/v[i]}。(注释: c [ i ] c[i] c[i]为当前物品能选多少个, m / v [ i ] m/v[i] m/v[i]是由于容量限制导致当前物品最多就能选 m / v [ i ] m/v[i] m/v[i]个,其中 / / /是 C + + C++ C++中的用法,表示下取整的除)。
我们会发现,这样高的时间复杂度过不去这个题目。那么,我们仔细观察一下 f f f的变化。
假如此时 n = 100000 , m > 9 × v [ i ] n=100000,m>9\times v[i] n=100000,m>9×v[i]设我们现在正在枚举 i i i,然后这个物品 i i i能选 2 2 2个,将 w [ i ] , v [ i ] w[i],v[i] w[i],v[i]简记为 w , v w,v w,v,将 f [ i − 1 ] [ j ] f[i-1][j] f[i−1][j]简记为