簡單0 1揹包

2021-07-05 14:49:23 字數 1351 閱讀 7010

第一次部落格求不噴不噴不噴!

有乙個容量為v的揹包,要裝進n個物品,第i個物品的費用為ci,價值為wi,要怎樣選擇才可以使花費不超過揹包容量的同時包裡的總價值最大?

(每個物品只能放一次)

當時剛接觸c++的我剛拿到題目就蒙逼了:如果乙個乙個列舉的話有很多種組合,想想心都累。所以就要利用動態規劃思想。什麼是動態規劃呢,其實我也不知道- -!反正就是個思想..

扯了那麼多我貌似還沒進入正題。。

假設dp[i][j]表示目前在第i個物品時目前花費為j的價值。狀態轉移方程為dp[i][j]=max(dp[i-1][j-c[i]]+w[i],dp[i][j])。

在方程中,dp[i-1][j-c[i]]表示在第i-1個物品並且目前花費為j-c[i]時的價值,w[i]表示第i個物品的價值。

於是,dp[i-1][j-c[i]]+w[i]表示從上乙個狀態轉移到這個狀態,即從dp[i-1][j-c[i]]+w[i]轉移到dp[i][j],這時候只要比較這兩個狀態的大小,價值大的保留,每次更新最優解。

因此核心**如下!

for(int i=0;i//列舉物品

for(int j=v;j>=c[i];j--)//從大到小列舉價值

dp[i][j]=max(dp[i-1][j-c[i]]+w[i],dp[i][j]);

大家(特別是有強迫症的同學)有沒有發現,為什麼第二層迴圈要從大到小?如果從小到大會怎麼樣?假設你 已經列舉到了i物品,這時候你的花費列舉到j,如果從小到大列舉的話,那之後當你列舉到j+c[i],你就會從dp[i][j]這個狀態轉移到dp[i][j+c[i]]這個狀態,這時候i物品已經被裝了兩次了有木有!(表達能力不好看不懂多看幾遍把)…

剛剛dp陣列開的是二維陣列,這次我們來給他壓縮成一維陣列。

dp[j]表示花費為j的時候所產生的最優價值。

因此轉移方程就出來了:dp[j]=max(dp[j],dp[j-c[i]]+w[i]);

這個方程表示列舉到第i物品並且花費為j時候:

1.第i-1個物品花費為j-c[i]時的狀態放上第i物品

2.i物品並且花費為j的狀態。

將這兩個狀態比較,求出最大的那個數就是列舉到i物品並且花費為j的狀態的最優解。於是**如下:

for(int i=0;i

i++)

for(int j=v;j>=c[i];j--)

dp[j]=max(dp[j],dp[j-c[i]]+w[i]);

這就是0-1的揹包的解法- -有錯誤請幫忙指出來,畢竟第一次發部落格求不噴!!

簡單01揹包

time limit 1000ms memory limit 65536k 有疑問?點這裡 這是個什麼問題呢?dp,貪心,資料結構,圖論,數論還是計算幾何?管他呢,反正胖巨巨都會,雖然胖巨巨走得早。現在有n個數xi,現在你要把這些數分成兩組a,b,使得abs sum a sum b 盡可能的小,並且...

簡單01揹包 完全揹包

01揹包問題 有n個重量和價值分別為wi,vi的物品。從這些物品中挑選出總重量不超過w的物品,求所有挑選方案中價值總和的最大值。1 n 100 1 wi,vi 100 1 w 10000 第一行輸入n的值 接下來n行輸入wi,vi 最後一行輸入w for example input 2 31 2 3...

簡單0 1揹包問題

有乙個揹包能裝的重量maxw 正整數,0 maxw 20000 同時有n件物品 0 n 100 每件物品有乙個重量wi 正整數 和乙個價值pi 正整數 要求從這n件物品中任取若干件裝入揹包內,使揹包的物品價值最大。第1行 揹包最大載重maxv,物品總數n 第2行到第n 1行 每個物品的重量和價值 乙...