背包相关问题总结

至多与恰好

如果问恰好装v,则初始化dp[]=INF,dp[0]=0。二维dp则初始化dp[][]=INF,dp[0][0]=0。(这样就能是那些能够恰好装满背包的物品的值为正数,而那些不能恰好装满背包的物品的值就为负数。)

如果问至多装v,则初始化dp[]=0

一定要注意,要求恰好时,分组背包枚举某一组的元素之前,要再设dp[j]=INF。(INF的值要够小!)

二维dp时(要求恰好),最开始的max也可能要设INF(除了第一次时)

01背包和完全背包枚举顺序

01背包是倒序,完全背包是顺序。

(若倒序枚举,j只会一直减小,所以我们总是用第i1个阶段向第i个阶段转移,是01背包。如果是正序,那么j有可能被jvi更新。j增大到j+vi时,又可能被j更新。这时两个都处于第i个阶段的状态之间发生了转移,相当于第i个物品被使用了两次,是完全背包。)

分组背包枚举顺序

先枚举是哪个组i,再倒序枚举体积j,最后再枚举每组组内元素k

(注意枚举顺序。i是阶段,ij共同构成状态,而k是决策。)

多重背包枚举顺序

思想:转化为共有i=1nki个物品的01背包问题(ki是每种物品的个数)。

先枚举是哪种物品i,再枚举i的个数j,最后再倒序枚举体积k,做01背包dp[k] = max(dp[k], dp[k - w[i]] + c[i])

注意res = max{dp[0 ~ v]}

二进制拆分法(优化多重背包)

原来的多重背包时间复杂度是O(Vi=1nki)的,效率较低。

我们可以把数量为ki的第i种物品拆成p+2个物品(p是满足20+21+22+...+2pki的最大整数)。

它们的体积分别为20wi,21wi,...,2pwi,riwiri=kii=0p2i)。

那么这p+2个物品可以且只能凑成0kiwi之间所有能被ki整除的数,这等价于原问题中体积为wi的物品可以使用0ki次。这时的复杂度是O(Vi=1nlog(ki))

posted @   andysj  阅读(103)  评论(0编辑  收藏  举报
编辑推荐:
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
点击右上角即可分享
微信分享提示