定義
考慮這樣一種物品,它并沒有固定的費用和價值,而是它的價值隨著你分配給它的費用而變化。這就是泛化物品的概念。
<p>更嚴格的定義之。在背包容量為V的背包問題中,泛化物品是一個定義域為0..V中的整數的函數h,當分配給它的費用為v時,能得到的價值就是h(v)。
<p>這個定義有一點點抽象,另一種理解是一個泛化物品就是一個數組h[0..V],給它費用v,可得到價值h[V]。{fuck!這不一樣啊!}
<p>[將所有的背包普遍化]:1.一個費用為c價值為w的物品,如果它是01背包中的物品,那么把它看成泛化物品,它就是除了h(c)=w其它函數值都為0的一個函數。2.如果它是完全背包中的物品,那么它可以看成這樣一個函數,僅當v被c整除時有h(v)=v/cw,其它函數值均為0。3.如果它是多重背包中重復次數最多為n的物品,那么它對應的泛化物品的函數有h(v)=v/cw僅當v被c整除且v/c<=n,其它情況函數值均為0。
<p>一個物品組可以看作一個泛化物品h。對于一個0..V中的v,若物品組中不存在費用為v的的物品,則h(v)=0,否則h(v)為所有費用為v的物品的最大價值。P07中每個主件及其附件集合等價于一個物品組,自然也可看作一個泛化物品。
泛化物品的和
如果面對兩個泛化物品h和l,要用給定的費用從這兩個泛化物品中得到最大的價值,怎么求呢?事實上,對于一個給定的費用v,只需枚舉將這個費用如何分配給兩個泛化物品就可以了。同樣的,對于0..V的每一個整數v,可以求得費用v分配到h和l中的最大價值f(v)。也即f(v)=max{h(k)+l(v-k)|0<=k<=v}。可以看到,f也是一個由泛化物品h和l決定的定義域為0..V的函數,也就是說,f是一個由泛化物品h和l決定的泛化物品。
<p>由此可以定義泛化物品的和:h、l都是泛化物品,若泛化物品f滿足
f(v)=max{h(k)+l(v-k)|0<=k<=v}
,則稱f是h與l的和,即f=h+l。這個運算的時間復雜度取決于背包的容量,是O(V^2)。
<p>泛化物品的定義表明:在一個背包問題中,若將兩個泛化物品代以它們的和,不影響問題的答案。事實上,對于其中的物品都是泛化物品的背包問題,求它的答案的過程也就是求所有這些泛化物品之和的過程。設此和為s,則答案就是s[0..V]中的最大值。
背包問題的泛化物品
一個背包問題中,可能會給出很多條件,包括每種物品的費用、價值等屬性,物品之間的分組、依賴等關系等。但肯定能將問題對應于某個泛化物品。也就是說,給定了所有條件以后,就可以對每個非負整數v求得:若背包容量為v,將物品裝入背包可得到的最大價值是多少,這可以認為是定義在非負整數集上的一件泛化物品。這個泛化物品——或者說問題所對應的一個定義域為非負整數的函數——包含了關于問題本身的高度濃縮的信息。一般而言,求得這個泛化物品的一個子域(例如0..V)的值之后,就可以根據這個函數的取值得到背包問題的最終答案。
<p>綜上所述,一般而言,求解背包問題,即求解這個問題所對應的一個函數,即該問題的泛化物品。而求解某個泛化物品的一種方法就是將它表示為若干泛化物品的和然后求之。
小結
本講可以說都是我自己的原創思想。具體來說,是我在學習函數式編程的 Scheme 語言時,用函數編程的眼光審視各類背包問題得出的理論。這一講真的很抽象,也許在“模型的抽象程度”這一方面已經超出了NOIP的要求,所以暫且看不懂也沒關系。相信隨著你的OI之路逐漸延伸,有一天你會理解的。
<p>我想說:“思考”是一個OIer最重要的品質。簡單的問題,深入思考以后,也能發現更多。