動態規劃之0 1揹包問題(簡單易懂)

2021-08-03 22:20:30 字數 2984 閱讀 9798

問題描述

現給定n種物品以及一容量為c的揹包,物品具有質量和價值兩個屬性,物品i的質量為wi,價值為vi。問如何選擇裝入揹包的物品,才能使得揹包中物品的總價值最大?

問題分析

給定資料為揹包容量c = 10, 物品種類n = 5, 物品質量w[n] = , 物品價值v[n] = 。

要解決這個問題,只需要以某種形式填寫下方這張表即可了解用動態規劃解決0-1揹包問題的思想。這張表的縱座標[0, 10]所表示的是揹包的容量,橫座標[1, 5]所表示的是物品的種類,為了後續的敘述方便,將表看作乙個二維陣列,並用小寫字母d來表示。

重量w價值v01

2345

6789

10126

2233

6545

4546

說明 填表

上文中我們已經知道了**中空位置所代表的含義,填這張表之前,還有以下兩點需要大家知道:

1. 這張表應該是由下至上,由左至右來進行填寫的;

2. 對於每一種物品,只對應著兩種狀態,裝入揹包和不裝入揹包;

知道了以上資訊後,便可以開始對這張表進行填寫了。

重量w價值v012

3456

78910

1262

2336

5454

5460

000

重量w價值v012

3456

78910

1262

2336

5454

5460

0006

6666

66填寫完第5行之後,接下來我們來填寫第4行:

重量w價值v012

3456

78910

1262

2336

5454

0000

6546

0000

6666

666

不將4號物品放入揹包可以得到的最大價值為6,將4號物品放入揹包中可以得到的最大價值為4,則在d[4][5]這個位置,所能形成的最大價值為6。

此時我們把錶填成了這樣:

重量w價值v01

2345

6789

10126

2233

6545

4000

0665

4600

0066

6666

6 接下來我們利用公式來繼續填寫這張表,d[4][6]位置,當前揹包的容量為j = 6,4號物品的重量為w[i] = 5,因為6 > 5,則選取第二個公式進行計算:

d[i + 1][j] = d[4 + 1][6] = d[5][6] = 6

d[i + 1][j - w[i]] + v[i] = d[4 + 1][6 - 5] + 4 = d[5][1] + 4 = 4

1和2中更大的值為6,則[4][6] = 6;

依此類推,可以將第四行剩下部分填寫完成,表變成如下所示:

重量w價值v012

3456

78910

1262

2336

5454

0000

6666

610105

4600

0066

6666

6 依次類推,因為3號物品的重量為6,所以d[3][0]~d[3][5]都使用公式1進行計算,第3行剩餘的部分使用公式2進行計算,這樣便可以完成第3行的填寫,填寫結果如下:

重量w價值v01

2345

6789

10126

2233

6500

0066

66610

11454

0000

6666

610105

4600

0066

6666

6 根據上述的講解,剩下的第2行和第1行填寫起來應該就不難了,請先試著填寫一下剩下的兩行,再向下進行閱讀。

最終**

通過上述的知識,最終可以得到這樣一張**:

重量w價值v01

2345

6789

10126

0066

991212

1515152

2300

3366

99910

11365

0000

6666

610114

5400

0066

66610

10546

0000

6666

666

通過這張表可以清晰的看出,這組資料可以得到的最大價值為15。

小改進按照上述的方法,我們已經可以計算出所需要的結果了,但是這裡有乙個小問題,再填寫最下面一行的時候,不能和其他行做到統一,因為它沒有下一行,沒有辦法實現上面公式中的操作,所以,我們可以在這個表下面多加一行,如下所示:

重量w價值v01

2345

6789

10126

2233

6545

4546

6000

0000

0000

00這樣的話,就不用單獨寫第5行的計算了,每一行的計算都遵循那兩個公式即可。

樣例**

#include

#include

#include

using

namespace

std;

const

int maxn = 20;

int d[maxn][maxn];

int w = ;

int v = ;

int main()}}

//輸出表

for(int i = 0; i < n; i++)

cout

<< d[0][c - 1] << endl; //**第一行的最後乙個值即最大價值

system("pause");

return

0;}

簡單0 1揹包問題 動態規劃

動態規劃最經典問題 0 1揹包問題,但是經典的0 1揹包問題給每個物品賦予兩種屬性 重量 價值 往往初次看此問題時難度較大。為了便於理解,先從經典的0 1揹包問題提取一種屬性進行分析 重量 題目如下 將上述過程轉化為 為 揹包中物品總重量的最大值 param weight 每個物品的重量陣列 par...

動態規劃之01揹包問題

首先是問題描述 給定n種物品和一揹包,物品i的重量是wi,其價值是pi,揹包的容量是m,問如何選擇裝入揹包中的物品總價值最大?可以這樣理解 揹包的揹負有上限,因此在這個上限內盡可能多的裝東西,並且價值越多越好。在這裡我之想討論動態規劃解決這個問題的詳細過程。動態規劃是用空間換時間的一種方法的抽象。其...

動態規劃之0 1揹包問題

問題描述 現有n件物品和乙個容量為c的揹包。第i件物品的重量是重量為w i 價值是v i 已知對於一件物品必須選擇取 用1表示 或者不取 用0表示 且每件物品只能被取一次 這就是 0 1 的含義 求放置哪些物品進揹包,可使這些物品的重量總和不超過揹包容量,且價值總和最大。求解思路 0 1揹包問題的遞...