多重背包
例题描述——暴力解法版本
DP分析法
多重背包问题和完全背包是很像的,完全背包问题中,物品是有无限件,但是多重背包中,对物品的数量进行了限制。
参考代码(C++版本)
例题描述——二进制优化
从道题的数据范围可以知道,假如直接暴力的话,1000 ∗ 2000 ∗ 2000 1000*2000*20001000∗2000∗2000 = 40亿,C++ 一秒大概是算107 ~ 108次,所以暴力是一定会超时的。
二进制优化的引入
倘若有个物品的个数S SS,S = 1023 S = 1023S=1023,想表示这个S SS,首先可以想到的是从0开始枚举到1023。但是很明显这种效率很低。
假如使用打包的想法,每个包裹中物品的个数依次是1 11、2 22、4 44、8 88、16 1616、… … 、512 512512。那么,使用这十个包裹,就可以拼凑出0~1023中的任意数,比如7,就使用包裹中物品个数为1+包裹中物品个数为2+包裹中物品个数为4的三个包裹。
二进制优化实例分析
倘若S SS= 200了?,继续按照2的整次幂进行划分
1 ,2,4,8,16,32,64,X XX。现在比较棘手的是最后一个包裹中物品的个数,它可以是128吗?假如是128,咱们从1累加到128,得到的是255,但是咱们只有200个物品,是凑不出来255的。
从1加到64是127,还差73。因此,当我们X XX补成73的时候,1到64是可以凑出0~127中的任意数,0到127中的任意拼法加上73,就可以凑出73到200中任意数,整合起来,咱们确实可以凑出从0到200中任意数。
咱们需要注意的是对X XX的限制,X XX是必须严格小于2k+1
具体的流程落实
参考代码(C++版本)
分组背包
例题描述
DP分析法
分组背包最主要的特点是关注选哪个组的第几个物品。
因为只能选择一个,就可以用分析01背包的方式进行分析了,只是在选择某组的第非0个物品时候,要具体落实到第几组的第几个物品,比如第i ii组的第k kk个物品