01揹包演算法

2022-05-30 03:33:10 字數 1860 閱讀 1968

**01揹包問題

動態規劃的基本思想:

動態規劃演算法可分解成從先到後的4個步驟:

1. 描述乙個最優解的結構,尋找子問題,對問題進行劃分。

2. 定義狀態。往往將和子問題相關的各個變數的一組取值定義為乙個狀態。某個狀態的值就是這個子問題的解(若有k個變數,一般用k維的陣列儲存各個狀態下的解,並可根    據這個陣列記錄列印求解過程。)。

3. 找出狀態轉移方程。一般是從乙個狀態到另乙個狀態時變數值改變。

4.以「自底向上」的方式計算最優解的值。

5. 從已計算的資訊中構建出最優解的路徑。(最優解是問題達到最優值的一組解)

其中步驟1~4是動態規劃求解問題的基礎,如果題目只要求最優解的值,則步驟5可以省略。

揹包問題

01揹包: 有n件物品和乙個重量為m的揹包。(每種物品均只有一件)第i件物品的重量是w[i],價值是p[i]。求解將哪些物品裝入揹包可使價值總和最大。

完全揹包: 有n種物品和乙個重量為m的揹包,每種物品都有無限件可用。第i種物品的重量是w[i],價值是p[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包重量,且價值總和最大。

多重揹包: 有n種物品和乙個重量為m的揹包。第i種物品最多有n[i]件可用,每件重量是w[i],價值是p[i]。求解將哪些物品裝入揹包可使這些物品的費用總和不超過揹包重量,且價值總和最大。

01揹包問題:

這是最基礎的揹包問題,特點是:每種物品僅有一件,可以選擇放或不放。

用子問題定義狀態:即c[i][v]表示前i件物品恰放入乙個重量為m的揹包可以獲得的最大價值。則其狀態轉移方程便是:

c[i][m]=max

這個方程非常重要,基本上所有跟揹包相關的問題的方程都是由它衍生出來的。所以有必要將它詳細解釋一下:「將前i件物品放入重量為m的揹包中」這個子問題,若只考慮第i件物品的策略(放或不放),那麼就可以轉化為乙個只牽扯前i-1件物品的問題。如果不放第i件物品,那麼問題就轉化為「前i-1件物品放入容量為v的揹包中」,價值為c[i-1][m];如果放第i件物品,那麼問題就轉化為「前i-1件物品放入剩下的重量為m-w[i]的揹包中」,此時能獲得的最大價值就是c[i-1][m-w[i]]再加上通過放入第i件物品獲得的價值p[i]。

**:

1 #include 2 #include 3 #include 4 #include 5 #include 6 #include 7

#define clr(a,b) memset(a,b,sizeof(a))

8#define inf 0x7f7f7f7f

9#define m 1050

10using

namespace

std;

11int v[200][200];//

前i個物品裝入容量為j的揹包中獲得的最大價值

12int max(int a,int

b)13

1819

int knapsack(int n,int w,int v,int x,int

c)20

40else

41 x[i]=0;42

}43 printf("

選中的物品是:\n");

44for(i=0; i)

45 printf("

%d "

,x[i]);

46 printf("\n"

);47

return v[n-1

][c];

4849}50

51int

main()

5275

/*76

1077578

3 4 5 3 2

793 2 6 4 3

80*/

view code

01揹包演算法

核心 狀態轉換方程 01揹包問題 容量為10的揹包,有5種物品,每種物品只有乙個,其重量分別為5,4,3,2,1,其價值分別為1,2,3,4,5。設計演算法,實現揹包內物品價值最大。如下 輸出14 include include using namespace std int main int v ...

演算法 01揹包

揹包最大容量10,有以下5個商品及其價值,試求揹包所能容納的最大價值。序號1 2345 重量226 54價值6 3546 如下 include include define max v 100 using namespace std struct good 動態規劃求解 n 商品個數 m 揹包最大重...

演算法(揹包問題 01揹包問題)

01揹包問題 有 n 件物品和乙個容量是 v 的揹包。每件物品只能使用一次。第 i 件物品的體積是 vi,價值是 wi。求解將哪些物品裝入揹包,可使這些物品的總體積不超過揹包容量,且總價值最大。輸出最大價值。輸入格式 第一行兩個整數,n,v,用空格隔開,分別表示物品數量和揹包容積。接下來有 n 行,...