看了許多的0-1揹包我感覺這乙個講的很清楚,推薦下。0-1揹包
問題描述:給定n種物品和一揹包。物品i的重量是w[i],其價值為v[i],揹包的容量為c。問應如何選擇裝入揹包的物品,使得裝入揹包中物品的總價值最大?
分析:對於一種物品,要麼裝入揹包,要麼不裝。所以對於一種物品的裝入狀態可以取0和1。設物品i的裝入狀態為xi,xi∈ (0,1),此問題稱為0-1揹包問題。
資料:物品個數n=5,物品重量w[5]=,物品價值v[5]=,總重量c=10。揹包的最大容量為10,那麼在設定陣列m大小時,可以設行列值為5和10,那麼,對於m(i,j)就表示可選物品為i到n且揹包容量為j(總重量)時揹包中所放物品的最大價值。看下面這個**即為動態規劃法解0-1揹包問題的過程:
**中灰色的為序號:列的1~5表示5個物品,橫向的1~10表示揹包的容量,綠色的列表示相對應物品的的重量,淺藍色的一列表示相對應物品的價值。假設新建乙個5*10的陣列對應中的棕色部分,棕色部分即為求解的過程,具體求解過程如下:
圖上所示的求解過程是從下往上求解,也就是說先分析第5個物品,最後分析第乙個物品。當揹包中為空的時候,考慮第5個物品,當揹包容量為1, 2, 3的時候這個揹包都是裝不下物品5的,因為物品5的重量是4,因此對應的當揹包容量為1, 3, 3的時候揹包裡面東西的價值(棕色**裡面的值)也是為0,當揹包容量大於等於4的時候揹包可以放下物品5,所以揹包裡面東西的價值就是6(因為這裡先只考慮只有一件物品5的時候),到此只有物品5的情況已經分析完畢;
接下來分析同時擁有物品5和物品4的情況,當揹包容量為1, 2, 3的時候,揹包裡面既放不下4物品也放不下5物品,所以揹包裡面物品的價值為0,當揹包容量大於等於4的時候,至少可以放下物品5了,這個時候就要取捨了,到底是將物品5放進去價值大還是將物品4放進去價值大,當揹包容量為4的時候,只能放進去物品5,價值為6,當揹包容量為5的時候如果選擇房屋物品4,那麼剩餘的揹包容量為0,查詢揹包重量為0的列(在前面步驟已經填充過的部分,這裡只填充了第5行第1列的位置),找這一列的最大值為0,所以選擇放物品4的時候揹包價值最大為4《不放物品4(剩餘揹包容量為5,查詢揹包容量5對應的填充過的部分,其最大值為6)時候的6,所以在揹包容量為5的時候的最優值是放物品5而不放物品4,一直分析到揹包容量為9的時候當選擇放入物品4的時候,剩餘揹包容量為4,再查詢揹包容量為4時候已經填充過的部分(即最後一行),可以查得最大值為6,所以這個時候選擇放入物品4可以獲得的最大價值為10。...
中間的過程都是如此,這裡再分析一下最後乙個物品的放置,揹包容量為2的時候,如果放入物品1,獲得的價值為6,剩餘揹包容量為0,剩餘揹包容量獲得的最大價值為0,所以6+0=6為最大價值,如果不放入1物品,剩餘揹包容量為2,剩餘揹包容量可以獲得的最大價值為3,所以最優的時候應該是放入物品1;揹包容量為3的時候,若放入1物品,獲得價值6,剩餘揹包容量1可以獲得的最大價值為0,所以放入物品1可以獲得的最大價值為6,如果不放入物品1,那麼剩餘揹包容量3可以獲得的最大價值(在已經填充過的部分查詢)為3,所以這時也是放入物品1為最優......當揹包容量為8的時候放入物品1獲得價值6,剩餘揹包容量6可以獲得最大價值為9,放入物品1的最大價值為6+9=15,如果不放入物品1,剩餘揹包容量8可以獲得的最大價值為9,所以此時也是放入物品1最優。
總結:通過上面的分析過程,可以歸結為:先考慮這個物品放入的時候可以獲得的最大價值(這個物品的價值+剩餘揹包(揹包總容量-該物品重量)容量可以獲得的最大價值),再考慮不放入這個物品的時候可以獲得的最大價值(剩餘揹包容量(此時就是揹包總重量)可以獲得的最大價值),然後將2者進行比較,那種結果的價值大就將哪種結果的價值儲存下來,依次類推。
#includeconst int c = 10; //揹包的容量
const int w = ;//物品的重量
const int v = ;//物品對應的待加
const int n = sizeof(w)/sizeof(w[0]) - 1 ; //n為物品的個數
int x[n];
void package0_1(int m[10],const int w,const int v,const int n)//n代表物品的個數
/*********************************放置前n-1個物品*********************************/
for(i = n-1; i >= 0; i--)
for(j = 1; j <= c; j++)
}
void answer(int m[10],const int n)
i -= 1;
x[n] = m[i][j] ? 1 : 0;
}
int main()
;
int i, j;
package0_1(m,w,v,n);
for(i = 0; i <= 4; i++)
answer(m,n);
printf("the best answer is:\n");
for(i = 0; i < 5; i++)
printf("%d ", x[i]);
printf("\n");
return 0;
}
動態規劃 01揹包
最優二叉查詢樹.cpp 定義控制台應用程式的入口點。01揹包問題。include stdafx.h include include define n 3 the number of real node define m 10 using namespace std int tmain int arg...
01揹包動態規劃
0 1揹包 問題描述 乙個旅行者有乙個最多能用 m公斤的揹包,現在有 n件物品,它們的重量 分別是w1,w2 wn,它們的價值分別為 c1,c2,cn.若每種物品只有一 件求旅行者能獲得最大總價值。輸入格式 w 第一行 兩個整數,m 揹包容量,m 200 和n 物品數量,n 30 w第2.n 1 行...
0 1揹包(動態規劃)
題意 有n件物品和乙個容量為v的揹包。第i件物品的體積是c i 價值是w i 求解將哪些物品裝入揹包可使價值總和最大。基本思路 這是最基礎的揹包問題,特點是 每種物品僅有一件,可以選擇放或不放。用子問題定義狀態 即f i v 表示前i件物品恰放入乙個容量為v的揹包可以獲得的最大價值。則其狀態轉移方程...