0,1揹包問題

2021-05-09 22:13:30 字數 3364 閱讀 9894

動態規劃:

問題描述:

設u = (一共有amount數量的物品)是一組準備放入揹包中的物品.設揹包的容量為size.

定義每個物品都具有兩個屬性weight和value.

我們要解決的問題就是計算在所選取的物品總重量不超過揹包容量size的前提下使所選的物品總價值最大.

程式的設計:

設v[i, j]用來表示從前i項中取出來的裝入體積為j的揹包的最大價值.i的範圍是從0到amount,j是從0到size.這樣的話要 計算的值就是v[amount, size].v[0, j]對於所有的j的值都是0,因為這時候的包中沒有物品.同時v[i, 0]的值也是0,因為沒有物品可以放到size為0的揹包裡面.

所以有:

v[i, j] = 0       若i = 0 或 j = 0;

v[i, j] = v[i - 1, j]    若j < ui.weight;(當物品的重量大於揹包承重時,就不把物品放在裡面)

v[i, j] = max      若i > 0並且j >= ui.weight;

現在就可用動態規劃的方法運用上面的公式來填表求解了.

#include

#define w 1000

#define n 1000

typedef struct data

...goods;

int returnmax(int a, int b)

...int knapsack(goods *p, int a, int s)

...mv = v[a][s];

return mv;

}int main()

...還有一種純粹用陣列解決的方案,避免了結構體的效率底下,思路是一樣的

**如下:

#include

#define goodnum 5

using namespace std;

int main()

...,...,...,...,...};//good[i][0]:size||good[i][1]:value

int i,j,size,weight;

int v[goodnum+1][1000];

coutfor(i=0;i<=goodnum;i++)

v[i][0]=0;

for(i=0;i<=size;i++)

v[0][i]=0;

for(i=1;i<=goodnum;i++)

for(j=1;j<=size;j++)...

cout《揹包問題 動態規劃

(2009-10-18 15:14:31)

標籤:動態規劃

if 節點

揹包 for

雜談 

分類:專業學習

01揹包問題描述:乙個旅行者有乙個最多能用m公斤的揹包,現在有n件物品,

它們的重量分別是w1,w2,...,wn,

它們的價值分別為p1,p2,...,pn.

若每種物品只有一件求旅行者能獲得最大總價值。

方式一:遍歷m*n的陣列,對應下圖包的總容量m=20,物品種類數n=5

**如下:

const int nres=5;//5種物品

int nresweight[nres+1]=;//每種物品對應重量

int nresvalue[nres+1]=;//每種物品對應價值

const int ntotlew=20;//揹包容量為20

int nvaluetable[nres+1][ntotlew+1]=;//動態價值表

int kitbag()

for(int i=1;i<=nres;i++)

for(int j=1;j<=ntotlew;j++)

if(nresweight[i]<=j) //容量大於等於當前物品重,j為當前包容量

if(nresvalue[i]+nvaluetable[i-1][j-nresweight[i]]>nvaluetable[i-1][j])

//如當前物品價值+包剩餘容量所能裝入最大價值》不裝當前物時包所能裝的最大價值,當前物品裝入包.

nvaluetable[i][j]=nresvalue[i]+nvaluetable[i-1][j-nresweight[i]];

else//當前物品不裝入包,當前包容量下的最大價值仍然是原來的價值

nvaluetable[i][j]=nvaluetable[i-1][j];

else//包容量不足以裝入當前物品時,沿用原來的包容量最大價值

**如下:

int recursionbag(int nr,int nw)//傳入資源數,包容量

if(nr==0||nw==0){

return 0;

if(nvaluetable[nr][nw]!=0){

//當前節點是已訪問過的節點,直接返回儲存的最優值

return nvaluetable[nr][nw];

if(nw>=nresweight[nr])//包容量大於等於當前物品重

{//獲得物品放入和不放入兩種情況中的價值最大者

nvaluetable[nr][nw]=max(nresvalue[nr]+recursionbag(nr-1,nw-nresweight[nr]),//物品入包後的價值

recursionbag(nr-1,nw));//物品不入包的最大價值

else//包容量不足以放入當前物品

nvaluetable[nr][nw]=recursionbag(nr-1,nw);

return nvaluetable[nr][nw];

對比兩種方式可知,第二種方式遍歷的資料量為黃色標註結點,要小於第一種方式的資料訪問量。

不過當節點深度上千後,如果包容量遠小2^n,比如為 10000,這時前一種方法要快得多。估計這時,遞迴對訪問過的節點雖然不再訪問它的子節點,但是這樣重複訪問到的父節點數量過於龐大。

揹包問題 01揹包問題

n個物品,總體積是v,每個物品的體積的vi,每個物品的最大價值是wi,在不超過v的體積下求最大價值 eg揹包容積為 5 物品數量為 4 物品的體積分別為 物品的價值分別為 思路定義乙個二位陣列int f new int n 1 v 1 f i j 就表示在1 i個物品中選取體積小於v的情況的最大價值...

揹包問題 01揹包

有n件物品和乙個容量為v的揹包。第i件物品的重量是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。01揹包中的 01 就是一種物品只有1件,你可以選擇放進去揹包即1,也可以選擇不放入揹包中即0。include include using namespace std const int ...

揹包問題(01揹包)

1085 揹包問題 在n件物品取出若干件放在容量為w的揹包裡,每件物品的體積為w1,w2 wn wi為整數 與之相對應的價值為p1,p2 pn pi為整數 求揹包能夠容納的最大價值。input 第1行,2個整數,n和w中間用空格隔開。n為物品的數量,w為揹包的容量。1 n 100,1 w 10000...