首先是問題描述:給定n種物品和一揹包,物品i的重量是wi,其價值是pi,揹包的容量是m,問如何選擇裝入揹包中的物品總價值最大?
可以這樣理解:揹包的揹負有上限,因此在這個上限內盡可能多的裝東西,並且價值越多越好。
在這裡我之想討論動態規劃解決這個問題的詳細過程。
動態規劃是用空間換時間的一種方法的抽象。其關鍵是發現子問題和記錄其結果。然後利用這些結果減輕運算量。因為揹包的最終最大容量未知,所以,我們得從1到m乙個乙個的試,比如,剛開始任選n件物品中的乙個,看對應的m的揹包,能不能放進去,如果能放進去,並且還有多少空間,則,多出來的空間能放n-1物品中的最大價值,怎麼能保證總選則是最大價值呢,看下表:
測試資料:
10,3
3,4
4,5
5,6動態規劃之01揹包問題
c[i][j]陣列儲存了1,2,3號物品依次選擇後的最大價值.
這個最大價值是怎麼得來的呢?從揹包容量為0開始,1號物品先試,0,1,2,的容量都不能放.所以置0,揹包容量為3則裡面放4.這樣,這一排揹包容量為4,5,6,….10的時候,最佳方案都是放4.假如1號物品放入揹包.則再看2號物品.當揹包容量為3的時候,最佳方案還是上一排的最價方案c為4.而揹包容量為5的時候,則最佳方案為自己的重量5.揹包容量為7的時候,很顯然是5加上乙個值了。加誰??很顯然是7-4=3的時候.上一排c3的最佳方案是4.所以。總的最佳方案是5+4為9.這樣.一排一排推下去。最右下放的資料就是最大的價值了。(注意第3排的揹包容量為7的時候,最佳方案不是本身的6.而是上一排的9.說明這時候3號物品沒有被選.選的是1,2號物品.所以得9.
從以上最大價值的構造過程中可以看出。
f(n,m)=max這就是書本上寫的動態規劃方程.
實現
#include
int c[10][100];
int knapsack(int
m,int n)
else
c[i][j]=c[i-1][j];
}return(c[n][m]);
}int main()
system("pause");
}
思路
問題的特點是:每種物品一件,可以選擇放1或不放0。
用子問題定義狀態:即f[i][v]表示前i件物品恰放入乙個容量為v的揹包可以獲得的最大價值。則其狀態轉移方程便是:
f[i][v]=max
這個方程非常重要,據說基本上所有跟揹包相關的問題的方程都是由它衍生出來的。所以詳細的查了一下這個方程的含義:「將前i件物品放入容量為v的揹包中」這個子問題,若只考慮第i件物品的策略(放或不放),那麼就可以轉化為乙個只牽扯前i-1件物品的問題。如果不放第i件物品,那麼問題就轉化為「前i-1件物品放入容量為v的揹包中」,價值為f[i-1][v];如果放第i件物品,那麼問題就轉化為「前i-1件物品放入剩下的容量為v-c[i]的揹包中」,此時能獲得的最大價值就是f[i-1][v-c[i]]再加上通過放入第i件物品獲得的價值w[i]。
在有的地方看到的揹包問題題目中,有兩種不太相同的問法。有的題目要求「恰好裝滿揹包」時的最優解,有的題目則並沒有要求必須把揹包裝滿。一種區別這兩種問法的實現方法是在初始化的時候有所不同。
如果是第一種問法,要求恰好裝滿揹包,那麼在初始化時除了f[0]為0其它f[1..v]均設為-∞,這樣就可以保證最終得到的f[n]是一種恰好裝滿揹包的最優解。
如果並沒有要求必須把揹包裝滿,而是只希望**盡量大,初始化時應該將f[0..v]全部設為0。
為什麼呢?可以這樣理解:初始化的f陣列事實上就是在沒有任何物品可以放入揹包時的合法狀態。如果要求揹包恰好裝滿,那麼此時只有容量為0的揹包可能被價值為0的nothing「恰好裝滿」,其它容量的揹包均沒有合法的解,屬於未定義的狀態,它們的值就都應該是-∞了。如果揹包並非必須被裝滿,那麼任何容量的揹包都有乙個合法解「什麼都不裝」,這個解的價值為0,所以初始時狀態的值也就全部為0了。
小結
01揹包問題是最基本的揹包問題,它包含了揹包問題中設計狀態、方程的最基本思想,另外,別的型別的揹包問題往往也可以轉換成01揹包問題求解。故仔細體會上面基本思路的得出方法。
動態規劃之01揹包問題
首先是問題描述 給定n種物品和一揹包,物品i的重量是wi,其價值是pi,揹包的容量是m,問如何選擇裝入揹包中的物品總價值最大?可以這樣理解 揹包的揹負有上限,因此在這個上限內盡可能多的裝東西,並且價值越多越好。在這裡我之想討論動態規劃解決這個問題的詳細過程。動態規劃是用空間換時間的一種方法的抽象。其...
動態規劃之0 1揹包問題
問題描述 現有n件物品和乙個容量為c的揹包。第i件物品的重量是重量為w i 價值是v i 已知對於一件物品必須選擇取 用1表示 或者不取 用0表示 且每件物品只能被取一次 這就是 0 1 的含義 求放置哪些物品進揹包,可使這些物品的重量總和不超過揹包容量,且價值總和最大。求解思路 0 1揹包問題的遞...
動態規劃之0 1揹包問題
問題描述 0 1揹包問題是應用動態規劃設計求解的典型例題 已知n種物品和乙個可容納c重量的揹包,物品i的重量為w i 產生的效益為p i 在裝包時物品i可以裝入,也可以不裝,但不可拆開裝。問如何裝包,所得裝包總效益最大。演算法分析 最優子結構特性 0 1揹包的最優解具有最優子結構特性。與一般揹包問題...