一、背包問題的描述
背包問題可以有多種形式,下面將對其逐一進行描述:
(1)經典的0-1背包問題(無物品的價值):
假設有一個能裝入容量為C的背包和n件重量分別為w1,w2,,...,wn的物品,能否從n件物品中挑選若干件恰好裝滿背包,要求找出所有滿足上述條件的解。
當C=10,各件物品重量為{1,8,4,3,5,2}時,可以找到下列4組解:(1,4,3,2)、(1,4,5)、(8,2)和(3,5,2)。
根據這個問題的一個變形是:
已知一個數為C,一個長度為n的無序的數組,分別是數w1,w2,...,wn,能否從這n個數中找到若干個數使其和等於數C,要求找出所有滿足上述條件的解。
(2)經典的0-1背包問題(有物品的價值):
給定n種物品和一個背包。物品i的重量是wi,其價值為vi,背包的容量為C。應該如何選擇裝入背包中的物品,使得裝入背包中物品的總價值最大?
上面的兩個問題都是0-1背包問題,因為隱含的信息是:對每種物品只有兩種選擇,即裝入背包或者不裝入背包。不能將物品裝入多次,也不能只裝入部分的物品。
(3)背包問題:與0-1背包問題類似,所不同的是在選擇物品i裝入背包時,可以選擇物品i的一部分,而不一定要全部裝入背包。
二、解決思路
對於問題(1),本文采用的是回溯思想,利用棧的“后進先出”的特性,首先將物品排成一列,然后順序選取物品裝入背包,假設已選取了前i件物品之后背包還沒裝滿,
則繼續選取第i+1件物品,若選該件物品的重量太大不能裝入,則放棄而繼續選取下一件,直至背包裝滿為止。但是如果在剩余物品中找不到合適的物品以填滿背包,則說明
“剛剛”裝入背包的那件物品“不合適”,應該將它取出,再繼續從它之后的物品中選取,如此重復,直至求得滿足要求的解,或者無解為止。因為回溯的規則也是“后進先出”,
所以采用棧這個數據結構。
對於問題(2),其實可以采用問題(1)的解法,因為要使價值最大化,肯定也是盡可能多的往背包里裝物品。只是此時不要求裝滿背包,而是在過程中不斷比較每種情況的
總價值,並找到總價值最大的選擇方式。
對於問題(3),這種背包問題可以用貪心算法求解,先計算每種物品單位重量的價值vi/wi;然后根據貪心策略,將可能多得單位重量價值最高的物品裝入背包;依次使用這種
策略,直至裝滿背包為止。
三、程序設計
問題(1):


問題(2):


問題(3):


