揹包問題--動態規劃

揹包問題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 }

 

  測試結果以下所示:

   

總結

揹包問題關鍵在於動態規劃,動態規劃關鍵在於公式的理解與掌握,加上實踐。

相關文章
相關標籤/搜索