题意简述
(按洛谷,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]为考虑前iii个物品,然后背包容量为jjj时的最优解。显然有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]\}f[i][j]=max{ f[i−1][j−k∗v[i]]+k∗w[i]},其中0<=k<=min{ 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++中的用法,表示下取整的除)。
我们会发现,这样高的时间复杂度过不去这个题目。那么,我们仔细观察一下fff的变化。
假如此时n=100000,m>9×v[i]n=100000,m>9\times v[i]n=100000,m>9×v[i]设我们现在正在枚举iii,然后这个物品iii能选222个,将w[i],v[i]w[i],v[i]w[i],v[i]简记为w,vw,vw,v,将f[i−1][j]f[i-1][j]f[i−1][j]简记为g(j)g(j)g(j)。然后开始第二层枚举jjj。
当
j=6v,f[i][j]=max{
g(6v),g(5v)+w,g(4v)+2w}j=5v,f[i][j]=max{

本博客探讨了如何使用单调队列优化来解决多重背包问题,通过分析f[i][j]的状态转移,揭示了在某些情况下可以利用滑动窗口和单调队列减少计算复杂度,从而求解价值最大的物品组合。文章提供了具体的思路分析和代码实现细节。
最低0.47元/天 解锁文章
313

被折叠的 条评论
为什么被折叠?



