0-1背包问题

0-1背包问题是一个典型的动态规划问题。

描述如下:现在又一个可以载重量为M的背包,另外有N个物品,每个物品重量和价值分别为w[i]和v[i],现在要求选择物品放入背包,使其在不超过重量的情况下有最大价值。

问题的递推表达式如下:设C为当前背包的容量。

  当w[n] > C时, f(n, C) = f(n-1, C)

  当w[n] <=C时, f(n, C) = max{f(n-1, C), v[n] + f(n-1, C-w[n])}

可以利用上式得到采用递归方法计算函数f的代码,递归结束是:f(i, 0) = 0或 f(0, j)=0.

 

另外也可以根据上面的最优子结构采用动态规划的方法,使用work[N+1][M+1]数组,其中work[i][j] 表示前i个物品放入载重量为j的背包中时能得到的最大价值。

以数据
10,3    //分别表示M和N
3,4     //表示每个物品的重量和价值
4,5
5,6

为例,得到的work矩阵如下:

   第一行,第一列一定均为0,j为1和2时,因为w[i] < j, 所以取 f(n-1, j),所以也都为0, 在以后的更新中,进行递推式比较,注意是将 f(n-1, j)和f(n-1, j-w[i])相比,所以只要当前物品重量w[i]小于背包总量j时即可进行是否加入的判断。代码如下:

 1 //0-1背包问题
 2 
 3 #include<iostream>
 4 #include<fstream>
 5 #include<vector>
 6 using namespace std;
 7 
 8 class Bag{
 9 public:
10     Bag(){}
11 
12     void parse(ifstream & fin);
13 
14     void getMaxValue();
15     
16 private:
17     int number;
18     int weight;    
19     vector<int> w;
20     vector<int> v;        //分别表示每个物品的重量和价值。
21 
22 };
23 
24 void Bag::parse(ifstream & fin)
25 {
26     fin >> weight >> number;
27 
28     int tempv, tempw;
29     w.push_back(0);
30     v.push_back(0);
31     for(int i = 0; i < number; i++)
32     {
33         fin >> tempw >> tempv;
34         w.push_back(tempw);
35         v.push_back(tempv);
36     }
37 }
38 
39 void Bag::getMaxValue()
40 {
41     vector<int> t(weight+1, 0);
42     vector<vector<int> > work(number+1,t);    //初始化number*weight的全0数组, 行表示前i个物品,被装入载重量为j的背包
43 
44     for(int i = 1; i <= number; i++)
45         for(int j = 1; j <= weight; j++)
46         {
47             if(w[i] <= j)    //注意,不要忘记等于的情况!!
48             {
49                 int temp = work[i-1][j-w[i]] + v[i];
50                 if(temp > work[i-1][j])
51                     work[i][j] = temp;
52                 else
53                     work[i][j] = work[i-1][j];
54             }else
55                 work[i][j] = work[i-1][j];
56         }
57 /////////////////结果输出
58     for(int i = 0; i <= number; i++)
59     {
60         for(int j = 0; j <= weight; j++)
61         {
62             cout << work[i][j]<< "  ";
63         }
64         cout << endl;
65     }
66     cout << "the max value is " << work[number][weight] << endl;
67 /////////////////////////////
68 }
69 

70 int main()
71 {
72     ifstream fin("in.txt");
73     Bag b;
74     b.parse(fin);
75     b.getMaxValue();
76 
77     system("pause");
78     return 0;
79 }

 

posted @ 2012-09-26 20:21  dandingyy  阅读(282)  评论(0编辑  收藏  举报