1. 定义
- 更严格的定义之。在背包容量为V 的背包问题中,泛化物品是一个定义域为0 … V 中的整数的函数h,当分配给它的费用为v时,能得到的价值就是h(v)。这个定义有一点点抽象,另一种理解是一个泛化物品就是一个数组h[0 …V ],给它费用v,可得到价值h[v]。
- 一个物品组可以看作一个泛化物品h。对于一个0 … V 中的v,若物品组中不存在费用为v的物品,则h(v) = 0,否则h(v)取值为所有费用为v的物品的最大价值。 6中每个主件及其附件集合等价于一个物品组,自然也可看作一个泛化物品。
泛化物品是崔作者总结的概念,使用函数定义最为恰当 h ( v ) , v ∈ 0... V h(v),v\in 0...V h(v),v∈0...V,特别的不同的物品对应不同的函数,并且按照泛化物品的性质对该函数进行一定的限制。
2. 泛化物品的和
- 如果给定了两个泛化物品h和l,要用一定的费用从这两个泛化物品中得到最大的价值,这个问题怎么求呢?事实上,对于一个给定的费用v,只需枚举将这个费用如何分配给两个泛化物品就可以了。同样的,对于0…V 中的每一个整数v,可以求得费用v分配到h和l中的最大价值f(v)。也即
f ( v ) = m a x { h ( k ) + l ( v − k ) ∣ 0 ≤ k ≤ v } f(v) = max\{h(k) + l(v − k) | 0 ≤ k ≤ v\} f(v)=max{h(k)+l(v−k)∣0≤k≤v}- 我们将f定义为泛化物品h和l的和: h、 l都是泛化物品,若函数f满足以上关系式,则称f是h与l的和。泛化物品和运算的时间复杂度取决于背包的容量,是O(V^2)。
- 由泛化物品的定义可知:在一个背包问题中,若将两个泛化物品代以它们
的和,不影响问题的答案。事实上,对于其中的物品都是泛化物品的背包问
题,求它的答案的过程也就是求所有这些泛化物品之和的过程。若问题的和
为s,则答案就是s(0…V )中的最大值。
原文没有提到第二点的时间复杂度为什么是$O(V^2)?可以看看下面的伪代码就明白了:
for v=0 to V
for k=0 to v//等价于 for k=v to 0
所以时间复杂度为 O ( V ∗ V / 2 ) = O ( V 2 ) O(V*V/2)=O(V^2) O(V∗V/2)=O(V2)。
3. 背包问题的泛化物品
- 一个背包问题中,可能会给出很多条件,包括每种物品的费用、价值等属性,物品之间的分组、依赖等关系等。但肯定能将问题对应于某个泛化物品。也就是说,给定了所有条件以后,就可以对每个非负整数v求得:若背包容量为v,将物品装入背包可得到的最大价值是多少,这可以认为是定义在非负整数集上的一件泛化物品。这个泛化物品——或者说问题所对应的一个定义域为非负整数的函数——包含了关于问题本身的高度浓缩的信息。一般而言,求得这个泛化物品的一个子定义域(例如0…V )的值之后,就可以根据这个函数的取值得到背包问题的最终答案。
- 综上所述,一般而言,求解背包问题,即求解这个问题所对应的一个函数,即该问题的泛化物品。而求解某个泛化物品的一种常用方法就是将它表示为若干泛化物品的和然后求之。
崔本人是做过很多题目,思考总结的结果。这里初学者很难体会这种思想,但是我们能确定几点:
- 抽象问题本身为 h ( v ) h(v) h(v)的函数。
- 拆分 h ( v ) = m a x { h 1 ( k 1 ) + h 2 ( k 2 ) + h 1 ( k 1 ) . . . + h n ( k n ) ) } , 0 < k 1 + k 2 + k 3 . . . . . . k n < V h(v)=max\{h_{1}(k_{1})+h_{2}(k_{2})+h_{1}(k_{1})...+h_{n}(k_{n}))\},0<k_{1}+k_{2}+k_{3}......k_{n}<V h(v)=max{h1(k1)+h2(k2)+h1(k1)...+hn(kn))},0<k1+k2+k3......kn<V
- 每个子函数 h n ( k n ) , 0 < k n < V h_{n}(k_{n}),0<k_{n}<V hn(kn),0<kn<V
- 根据物品性质确定如何划分 h n ( k n ) h_{n}(k_{n}) hn(kn),特别的每个子函数同样符合 h ( v ) h(v) h(v)的思想,可以继续拆分。