0 1揹包問題的兩種動態規劃演算法思想

2021-07-29 07:17:59 字數 2480 閱讀 6366

/*

name: 0-1揹包問題的兩種動態規劃演算法思想

author: 巧若拙

date: 07-03-17 15:30

description:

給定n中物品和乙個容量為c的揹包,物品i的重量為wi,其價值為vi,

0-1揹包問題是如何選擇裝入揹包的物品(物品不可分割),使得裝入揹包的物品的價值為最大。

1.題目分析:

考慮到每種物品只有2種選擇,即裝入揹包或不裝入揹包,並且物品數和揹包容量已給定,

要計算裝入揹包物品的最大價值和最優裝入方案,可用動態規劃演算法思想。

2.演算法設計:

a. 物品有n種,揹包容量為c,分別用p[i]和w[i]儲存第i種物品的價值和重量,用

x[i]標記第i種物品是否裝入揹包,用陣列p[n][c]記錄給定n個物品裝入容量為c的揹包的最大價值。

動態規劃有兩種基本思路,一種是自頂而下的備忘錄演算法,它採用遞迴的方式,一步步縮小問題的規模,

找到邊界(n==0)以後,處理好邊界(bestp = (c >= w[n]) ? p[n] : 0;),然後一步步返回,返回更大問題的解。

每獲得乙個子問題的答案,便儲存到備忘錄陣列p[n][c],避免下次充分計算,提公升了效率。

另一種思路是自底向上的動態規劃演算法,它從最小的子問題(只包含0號物品)開始處理,然後依次增加可裝物品的數量,

用陣列p[n][c]記錄每乙個已處理子問題的答案,由於0-1揹包問題具有最優子結構,

每個問題的最優解都是由其子問題的最優解組成,故這樣依次遞增問題的規模,可以得到最終需要的最優解。

3. 複雜度分析:

無論是自頂向下的備忘錄演算法還是自底向上的動態規劃演算法,都可以在o(n^3)時間內求解。

他們有o(n^2)個備忘記錄項(或子問題),這些記錄項的初始化耗費o(n^2)時間。

每個記錄項只填入一次,每次填入時,耗費o(n)時間。因而填入o(n^2)各記錄項總共耗費o(n^3)時間。

對每個子問題,兩種方法都只解一次,並記錄答案,再碰到該子問題時,不重新求解而是取用已有答案。

它們節省了計算量,提高了演算法的效率。自底向上的動態規劃演算法按順序計算了每個子問題的解;

自頂向下的備忘錄演算法採用遞迴的方式只計算了確實需要求解的子問題,效率更高(當然,由於需要呼叫遞迴函式,

有了一些額外的開銷),也更便於理解。 */

#include#includeusing namespace std;

const int cmax = 40; //揹包最大容量

const int n = 4; //物品的個數

int w[n] = ;//物品的重量

int p[n] = ;//物品的價值

int x[n]; //解向量

int b[n][cmax+1]; //備忘錄,記錄給定n個物品裝入容量為c的揹包的最大價值

int sum = 0;

int best(int n, int c); //備忘錄:自頂而下,獲得給定n個物品裝入容量為c的揹包的最大價值

int best_2(int n, int c);//動態規劃:自底而上,獲得給定n個物品裝入容量為c的揹包的最大價值

int max(int a, int b);

int main()

else

} x[0] = (b[0][c] > 0) ? 1 : 0; //是否裝第0個物品

bestw += (x[0] == 0) ? 0 : w[0];

cout << "揹包的最大價值:" << bestp << "(" << bestw << ")" << endl;

cout << "揹包的最優解:";

for (int i=0; ib) ? a : b;

}int best(int n, int c)//備忘錄:自頂而下,獲得給定n個物品裝入容量為c的揹包的最大價值

int bestp = 0;

if (n == 0)//處理第0個物品,即只有乙個物品

else }

b[n][c] = bestp;//做備忘錄

cout << (++sum) << ": " << "b[" << n << "][" << c << "] = " << b[n][c] << endl;

return bestp;

}int best_2(int n, int c)//動態規劃:自底而上,獲得給定n個物品裝入容量為c的揹包的最大價值

for (int j=w[0]; j<=c; j++)

//記錄前i(i>=1)個物品裝入容量為0-c的揹包的最大價值

for (int i=1; ib[i-1][j-w[i]]+p[i]) ? b[i-1][j] : b[i-1][j-w[i]]+p[i];

} }//第n個物品只需考慮容量為c的一種情況

b[n][c] = b[n-1][c];

if (c >= w[n])

return b[n][c];

}

01揹包問題 (動態規劃演算法)

0 1 揹包問題 給定 n 種物品和乙個容量為 c 的揹包,物品 i 的重量是 wi,其價值為 vi 問 應該如何選擇裝入揹包的物品,使得裝入揹包中的物品的總價值最大?分析一波 面對每個物品,我們只有選擇拿取或者不拿兩種選擇,不能選擇裝入某物品的一部分,也不能裝入同一物品多次。解決辦法 宣告乙個 大...

01揹包問題 (動態規劃演算法)

題目 給定n種物品和乙個容量為v的揹包,物品i的體積是wi,其價值為ci。每種物品只有乙個 問 如何選擇裝入揹包的物品,使得裝入揹包中的物品的總價值最大?面對每個物品,我們只有選擇放入或者不放入兩種選擇,每種物品只能放入一次。我們用之前同樣的思路來走一遍試試 假設只剩下最後一件物品,我們有兩種選擇 ...

動態規劃演算法 01揹包問題

動態規劃演算法通常用於求解具有某種最優性質的問題。在這類問題中,可能會有許多可行解。每乙個解都對應於乙個值,我們希望找到具有最優值的解。動態規劃演算法與分治法類似,其基本思想也是將待求解問題分解成若干個子問題,先求解子問題,然後從這些子問題的解得到原問題的解。與分治法不同的是,適合於用動態規劃求解的...