動態規劃0-1揹包問題
阿新 • • 發佈:2019-02-14
Ø
問題描述:
給定n種物品和一揹包。物品i的重量是wi,其價值為vi,揹包的容量為C。問應如何選擇裝入揹包的物品,使得裝
入揹包中物品的總價值最大?
Ø
對於一種物品,要麼裝入揹包,要麼不裝。所以對於一種物品的裝入狀態可以取0和1.我們設物品i的裝入狀態為xi,xi∈ (0,1),此問題稱為0-11揹包問題。
過程分析
資料:物品個數n=5,物品重量w[n]={0,2,2,6,5,4},物品價值V[n]={0,6,3,5,4,6},
(第0位,置為0,不參與計算,只是便於與後面的下標進行統一,無特別用處,也可不這麼處理。)總重量c=10.
Ø揹包的最大容量為10,那麼在設定陣列m大小時,可以設行列值為6和11,那麼,對於m(i,j)就表示可選物品為i…n揹包容量為j(總重量)時揹包中所放物品的最大價值。
下面是自己寫的原始碼:
[cpp] view plaincopyprint?- #include<stdio.h>
- #include<stdlib.h>
- #include<iostream>
-
#include<queue>
- #include<climits>
- #include<cstring>
- usingnamespace std;
- constint c = 10; //揹包的容量
- constint w[] = {0,2,2,6,5,4};//物品的重量,其中0號位置不使用 。
- constint v[] = {0,6,3,5,4,6};//物品對應的待加,0號位置置為空。
- constint n = sizeof(w)/sizeof(w[0]) - 1 ; //n為物品的個數
- int x[n+1];
-
void package0_1(int m[][11],constint w[],const
- {
- //採用從底到頂的順序來設定m[i][j]的值
- //首先放w[n]
- for(int j = 0; j <= c; j++)
- if(j < w[n]) m[n][j] = 0; //j小於w[n],所對應的值設為0,否則就為可以放置
- else m[n][j] = v[n];
- //對剩下的n-1個物品進行放置。
- int i;
- for(i = n-1; i >= 1; i--)
- for(int j = 0; j <= c; j++)
- if(j < w[i])
- m[i][j] = m[i+1][j];//如果j < w[i]則,當前位置就不能放置,它等於上一個位置的值。
- //否則,就比較到底是放置之後的值大,還是不放置的值大,選擇其中較大者。
- else m[i][j] = m[i+1][j] > m[i+1][j-w[i]] + v[i]?
- m[i+1][j] : m[i+1][j-w[i]] + v[i];
- }
- void answer(int m[][11],constint n)
- {
- int j = c;
- int i;
- for(i = 1; i <= n-1; i++)
- if(m[i][j] == m[i+1][j]) x[i] = 0;
- else {
- x[i] = 1;
- j = j - w[i];
- }
- x[n] = m[i][j] ? 1 : 0;
- }
- int main()
- {
- int m[6][11]={0};
- package0_1(m,w,v,n);
- for(int i = 0; i <= 5; i++)
- {
- for(int j = 0; j <= 10; j++)
- printf("%2d ",m[i][j]);
- cout << endl;
- }
- answer(m,n);
- cout << "The best answer is:\n";
- for(int i = 1; i <= 5; i++)
- cout << x[i] << " ";
- system("pause");
- return 0;
- }