首页 > 编程知识 正文

多选择背包问题,01多背包问题

时间:2023-05-04 17:03:07 阅读:22352 作者:2293

主题有n种物品和容量为v的背包,每个物品可以无限次使用。

解决方案:将这些物品放入背包后,物品的总消费费用不会超过背包的容量,且价值总和最大。

基本思想问题类似于01背包问题,不同的是每个物品有无数个,不是每个物品拿不拿,

采取一些问题。 当然一种物品最多不超过[V/Ci]件。 首先按照01背包问题的想法来理解吧

设f[i,v]的前I种物品正好放入容量v的背包中的最大值

状态转移方程

F[i,v]=max(f[I-1,v-k Ci] kWi ) )0=k*Ci=v ) ) ) ) ) )

和01背包问题一样,有o(NV )个状态解,但由于各状态的k不确定,各状态的时间也不是常数,所以总的复杂度很大。

想想简单的优化吧。 我们想让价值最大化。 需要的东西必然体积越小越好。 价值越大越好,但需要注意的是,

并不是单位体积的价值越大越好。

所以,如果物品一的体积小于物品二,而且物品一的价值大于物品二,我们就可以完全扔掉物品二。 这是确实的,

把价值小体积大的换成价值大体积小的,绝对不会吃亏。 当然,这不能改变最坏情况的时间复杂性

也许一个特别的数据都不用去除。

这个优化可以简单地用o(n ) 2来实现,反而可以接受。 当然,也可以用同样的方法选择同样费用中价值最高的。

剩下的可以扔掉。

01转变为背包问题最简单的想法是将第I项转变为“[V/Ci]”项的费用和价值与I项相同。 这种时间复杂性没有得到改善,

但是,这表明了向01背包转换的想法,即把一个物品分解成多个取或不取的物品。 当然,还有更有效的方法。 第I个

物品分解为费用为Ci2k、价值为Wi2k的几个物品,k满足条件Ci2^k=V。

这是二进制思想,这样在时间复杂性方面是很大的改善。

O(NV )算法该算法使用一维数组:

Fori1吨

forvcitov

f [ v ]max (f [ v ],f[v-Ci] Wi ) )。

可见这只是与01背包伪代码的第二个循环的顺序不同。

但是这是为什么呢? 首先,让我们来看看我们01背包为什么按v的降序循环。 首先,要保留上次的循环

数据是第i-1项的数据。 也就是为了保证f[i,v]从f[i-1,v-Ci]递归地传输,这也是01背包的密钥

这个东西拿不拿? 但是,完全的背包问题不需要考虑拿还是不拿,只考虑拿几件。 01背包子问题的关键是

第I项和第一个i-1项的取法,但完全背包问题子问题的关键是容量v的最大价值,所以它需要的子结果是

可能已经被选为I件物品的子结果f[i,v-Ci]。

上面两个for环的位置可以反转位置。 要说为什么,画画就知道了。 为什么要反转位置,是因为需要带来时间上的优化。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。