乙個揹包總容量為v,現在有n個物品,第i個 物品體積為weight[i],價值為value[i],現在往揹包裡面裝東西,怎麼裝能使揹包的內物品價值最大?
例題:給定乙個數m,將m拆成不同的自然數的和的形式有多少種方案,這就是典型的01揹包問題,揹包容量為m,物品件數為k,這裡面的k是隱含條件,可以求出來,因為m最多由1+2+…+k得到,由此可以根據m求得物品件數的上限。
乙個揹包總容量為v,現在有n個物品,第i個 物品體積為weight[i],價值為value[i],每個物品都有無限多件,現在往揹包裡面裝東西,怎麼裝能使揹包的內物品價值最大?
例題:假設現在有1元、2元、5元的紙幣很多張,現在需要20塊錢,你能給多少種找錢方案,這就可以認為是完全揹包問題,即揹包容量為20,物品體積分別為1、2、5。
給予不同面值的硬幣若干種種(每種硬幣個數無限多),如何用若干種硬幣組合為某種面額的錢,使硬幣的的個數最少?
在現實生活中,我們往往使用的是貪心演算法,比如找零時需要13元,我們先找10元,再找2元,再找1元。如果我們的零錢可用的有1、2、5、9、10。我們找零18元時,貪心演算法的策略是:10+5+2+1,四種,但是明明可以用兩個9元的啊。這種問題一般使用動態規劃來解決。
一、首先來看01揹包問題
用乙個陣列f[i][j]表示,在只有i個物品,容量為j的情況下揹包問題的最優解。第i個物品可以選擇放進揹包或者不放進揹包(這也就是0和1),假設放進揹包(前提是放得下),那麼f[i][j]=f[i-1][j-weight[i]+value[i];如果不放進揹包,那麼f[i][j]=f[i-1][j]。
這就得出了狀態轉移方程:
f[i][j]=max(f[i-1][j],f[i-1][j-weight[i]+value[i])
二、完全揹包問題 和 硬幣找零問題
其實這個兩個問題非常相似,都是物品數目無限多,乙個是不超過某個重量值w求最大value,乙個是要獲得某個value,求最小重量(每個硬幣可以看成是重量為1的物品)。
(1)對於完全揹包問題狀態轉移方程:
f[ i ] [ j ] = max( f[i-1][j], f[ i ][ j- weight[i] ] + value[i] ) ,注意後面是f[i, j-weight[i]],i 沒有減1
可以理解為:j為揹包可以容納的重量,有i種物品時,對於第i種物品,要麼取或者不取,至於取多少個我們並不關心。
(2)對於硬幣找零問題狀態轉移方程:
f[i][j]=min( f[i-1][ j ], f [i ] [ j - value[i] ] + 1) ,注意後面是f[i, j-value[i]],i 沒有減1
可以理解為:j為需要找零多少元,有i種硬幣,找零時對於第i種硬幣,我們只考慮取或者不取,至於取多少個我們並不關心!
兩種邊界情況說明一下:
(1)f[0][j]=integer.maxvalue ,因為 對金額為 j 的錢找零,但是可以的硬幣面值種類為0,這顯然是無法做到的。其實這是乙個」未定義「的狀態。它之所以初始為integer.maxvalue
(2)f[i][0]=0,因為,對金額為0的錢找零,可用來找零的硬幣種類有 i 種,金額為0怎麼找啊,故設定為0。
動態規劃 常見做法 填表法
填表法,是dp最常見的做法。以未知的量為基礎,通過已知的量來重新整理當前的未知量。這是dp最基礎的做法。通常,我們大多題目都可以用這種方法實現。楊輝三角 description 楊輝三角是二項式係數在三角形中的一種幾何排列。它的每個數等於它上方兩數之和,每行數字左右對稱,由 1 開始逐漸變大。1 1...
動態規劃常見思路分享總結
那幾乎可以肯定,考察的是動態規劃技巧,時間複雜度一般都是 o n 2 int n array.length int dp newint n for int i 1 i n i 符合歸納法,可以找到狀態轉移的關係。int n arr.length int dp newdp n n for int i ...
動態規劃 常見揹包問題合集
01揹包 有n件物品和乙個容量為v的揹包。每件物品只有一件 第i件物品的費用是c i 價值是v i 求解將哪些物品裝入揹包使總價值最大。轉移方程 f i v max,可以優化只用一維陣列.如下 for int i 0 i w i j if record j c i v i record j reco...