它這個問題問的是,在有限的容量下,能裝下的最大價值是多少。
所以我們可以遞迴求解,記憶性遞迴,用二維陣列,但是這樣的話就會超記憶體,所以我們只能用動規來寫,而且不能開二維陣列,
只能用滾動陣列。
我們設乙個f陣列,大小為13000,它存的是容積為m的揹包可放下的最大價值。
我們先假設乙個二維陣列f [ i ][ j ] ,它表示的意思是,揹包裡放 i 個物品,最大價值為 j ,它的最大價值。
我們可以知道 f [ i ][ j ] = max ( f [ i-1][ j ] ,f[ i-1][ j-w[i] ] +value [ i ] ) 。
它的意思是,f [ i ][ j ]的值來自於如果不選第 i 個物品,放下值為 j 的包的最大價值,和如果選第 i 個物品,揹包裡放下 j-weight[i] 大小物品的最大價值和第 i 個物品價值之和,經過比較之後最大的那個值。
我們對於f [ i ][ j ]可以選也可以不選,不選的話,它的價值就是f [ i-1 ][ j ] ,選的話它的價值就是f[ i-1][ j-w[i] ] +value [ i ] ,就是在原揹包容積減去 i 物品的重量之後,放入 i-1 個物品的最大價值與 i 物品的價值之和。
不過有個條件,如果 j-w[i] >=0 ,我們才比較求解,小於它的話,我們就讓它等於它的上一行同列的值。
好,那麼問題來了,這個問題怎麼在一維陣列中求解呢?
首先我們要知道,在二維陣列裡面它們的形態:
f[ i-1][ j-w[i] ] f [ i-1][ j ]
f [ i ][ j ] f[ i ][ 2j-w[i] ]
所以說,對於f [ i-1 ][ j ] ,我們還是有用的,我們要用來求右下角的那個元素,我們不能正向,由小到大直接把f [ i-1 ][ j ]覆蓋掉,我們應該在用完它時候,再覆蓋掉,所以我們從右向左求,就不會傷害任何值了。
**如下:
#include using namespace std;
int w[3600],d[3600],f[13000];
int main()
for (int i=1;i<=n;i++)
} cout
}
動態規劃 (01揹包 poj3624 )
關於揹包問題 眾所皆知,這裡講給出關於揹包問題的一些簡介 乙個旅行者準備隨身攜帶乙個揹包 可以放入揹包的物品有n 種 每種物品的重量和價值分別為 wj vj 如果揹包的最大重量限制是 b,怎樣選擇放入揹包的物品以使得揹包的價值最大?題目就是這麼簡單 先思考乙個問題 就是每種物品可以重複選擇,這種要怎...
動態規劃之0 1揹包問題(POJ3624)
有n件物品和乙個容積為m的揹包。第i件物品的體積w i 價值是d i 求解將哪些物品裝入揹包可使價值總和最大。每種物品只有一件,可以選擇放或者不放。n 3500,m 130000 解題思路 用f i j 表示取前i種物品,使它們總體積不超過j的最優取法取得的價值總和。遞推 f i j max f i...
POJ 1276 多重揹包問題
題目在 題目大意是說,我現在要從atm中取錢,m atm裡面有若干種貨幣,每一種都有對應的貨幣面額和張數。問現在atm能夠取出來的 小於等於m的最大金額。若將m理解為揹包重量,而每種貨幣的面額理解成 value,貨幣的面額同樣理解成重量,那麼這個問題就是乙個多重揹包問題。多重揹包問題可以轉換成完全揹...