揹包問題ios
0-1揹包問題涉及最值的獲取,普通的測試方法很可貴到結果,須要採動態規劃方法。公式以下:測試
其中,c[i,w]表示在包含了i物品的狀況下揹包承重爲w下揹包的最大價值。若是物品i重量大於w,直接跳過;若是物品i重量小於w,分爲兩種狀況:spa
(1)i物品裝入,則要判斷剩餘i-1個物品在重量爲w-wi前提下最大價值+i物品自己價值;.net
(2)i物品不裝入,判斷剩餘i-1物品在質量爲w下最大價值,這是解題的關鍵;code
題目描述:blog
有編號分別爲a,b,c,d,e的五件物品,它們的重量分別是2,2,6,5,4,它們的價值分別是6,3,5,4,6,如今給你個承重爲10的揹包,如何讓揹包裏裝入的物品具備最大的價值總和?ci
name | weight | value | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
a | 2 | 6 | 0 | 6 | 6 | 9 | 9 | 12 | 12 | 15 | 15 | 15 |
b | 2 | 3 | 0 | 3 | 3 | 6 | 6 | 9 | 9 | 9 | 10 | 11 |
c | 6 | 5 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 11 |
d | 5 | 4 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 10 | 10 |
e | 4 | 6 | 0 | 0 | 0 | 6 | 6 | 6 | 6 | 6 | 6 | 6 |
表格生成過程是從下至上,從左到右的,d2含義:只有物品d時,有個承重爲2的揹包,那麼這個揹包的最大價值是0,由於d物品的重量是5.io
下面說說a8推理過程以下:表格來自:http://blog.csdn.net/mu399/article/details/7722810table
(1)因爲物體a質量2<8,所以根據推導公式判斷b8和 b6+6(value)兩者取大值class
(2)由表可知,b8=9,b6=9, b6+6(value)=15,因此取值15;
其它取值過程相似。
代碼實現以下:
1 #include<iostream> 2 using namespace std; 3 int c[200][200];//前i個物品裝入容量爲j的揹包中得到的最大價值 4 int max(int a,int b) 5 { 6 if(a>=b) 7 return a; 8 else return b; 9 } 10 11 int KnapSack(int n,int w[],int v[],int x[],int C)//w 物品的重量 v物品的價值 x 物品的選取狀態 C揹包最大容量 12 { 13 int i,j; 14 for(i=0;i<=n;i++) 15 c[i][0]=0; 16 for(j=0;j<=C;j++) 17 c[0][j]=0; 18 for(i=0;i<=n-1;i++) 19 for(j=0;j<=C;j++) 20 if(j<w[i])//i物品重量超過j 21 c[i][j]=c[i-1][j]; 22 else 23 c[i][j]=max(c[i-1][j],c[i-1][j-w[i]]+v[i]);//不選用i物品和選用i物品之間選最大的 24 j=C; 25 for(i=n-1;i>=0;i--) 26 { 27 if(c[i][j]>c[i-1][j])//選用i物品 28 { 29 x[i]=1; 30 j=j-w[i]; 31 } 32 else 33 x[i]=0; 34 } 35 cout<<"the select ting:"<<endl; 36 for(i=0;i<n;i++) 37 cout<<x[i]<<" "; 38 cout<<endl; 39 return c[n-1][C]; 40 41 } 42 43 int main() 44 { 45 int s;//得到的最大價值 46 int w[15];//物品的重量 47 int v[15];//物品的價值 48 int x[15];//物品的選取狀態 49 int n,i; 50 int C;//揹包最大容量 51 cout<<"enter the max weight:C="; 52 cin>>C; 53 cout<<"enter the number :n="; 54 cin>>n; 55 cout<<"enter the weight of n thing:"; 56 for(i=0;i<n;i++) 57 cin>>w[i]; 58 cout<<"enter the value of n thing:"; 59 for(i=0;i<n;i++) 60 cin>>v[i]; 61 s=KnapSack(n,w,v,x,C); 62 cout<<"the max value:"<<s; 63 return 0; 64 65 }
測試結果以下所示:
總結
揹包問題關鍵在於動態規劃,動態規劃關鍵在於公式的理解與掌握,加上實踐。