所有物品分成K类,每类最多只能选择一件物品的背包问题。
有 \(N\) 件物品和一个容量为 \(V\) 的背包。第 \(i\) 件物品的重量是 \(C_i\),价值是 \(W_i\)。这些物品被划分为\(K\)组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
这个问题变成了每组物品有若干种策略:是选择本组的某一件,还是一件都不选。也就是说设\(F [k, v]\)表示前\(k\)组物品花费费用\(v\)能取得的最大权值,则有: \[ F[k, v]=\max \left\{F[k-1, v], F\left[k-1, v-C_{i}\right]+W_{i} \mid \text { item } i \in \operatorname{group} k\right\} \] 使用一维数组的伪代码是:
代码如下:
1 | /* |
简单优化:
若若两件物品\(i\)、\(j\)满足\(W_i ≤ W_j\)且\(V_i ≥ V_j\),则将可以将物品\(j\)直接去掉,不用考虑。
这个优化的正确性是显然的:任何情况下都可将价值小费用高的 \(j\) 换成物美价廉的\(i\),得到的方案至少不会更差。对于随机生成的数据,这个方法往往会大大减少物品的件数,从而加快速度。然而这个并不能改善最坏情况的复杂度,因为有可能特别设计的数据可以一件物品也去不掉。