dp之完全背包

完全背包问题:

  有n种价值和重量分别为vi, wi的物品。从这些物品中挑选总重量不超过W的物品,求挑出物品总合的最大值

 

*

*

*

*

*

我不会。。。代码算是背下来了,,,很简单,就几行,,,但是,,,,很尴尬。。。我就放到这,记录dp大法修炼之路的艰辛(用了一天来理解/(ㄒoㄒ)/~~)

代码:

 1 #include <iostream>
 2 
 3 using namespace std;
 4 int M[105][10005];
 5 int v[105], w[105];
 6 int main()
 7 {
 8     int n, W;
 9     cin >> n >> W;
10     for(int i = 0; i < n; i++)
11         cin >> w[i] >> v[i];
12     for(int i = 0; i < n; i++)
13     {
14         for(int j = 0; j <= W; j++)
15         {
16             if(w[i] > j) M[i+1][j] = M[i][j];
17             else M[i+1][j] = max(M[i][j], M[i+1][j-w[i]] + v[i]);
18         }
19     }
20     cout << M[n][W] << endl;
21 }

好吧,,其实是看懂了一点的,M[i][j],状态是从前i个物品挑选价值尽可能大的但是体积不超过j的物品。一个一个枚举,一开始的代码是这样的

1 for(int i = 0; i < n; i++)
2     {
3         for(int j = 0; j <= W; j++)
4         {
5             for(int k = 0; k * w[i] <= j; k++)
6                 M[i+1][j] = max(M[i+1][j], M[i][j-w[i]*k] + v[i]*k);
7         }
8     }

三重循环,最坏结果是W*n^2, 经过很长的分析(在书上),,,发现M[i+1][j]中选择k的情况和前面M[i+1][j-w[i]]中选择k-1的情况是相同的 。。。恩,这就是我理解的最大程度了,,,,后来一长串公式就把一个循环消掉了!!!、、、、智商不够,,,暂时先放在这,,等再做几道dp题再来。。。

 

posted on 2017-03-25 19:43  子狼  阅读(171)  评论(0)    收藏  举报

导航