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题再来。。。

print “ 欢迎来到渣小狼的博客,这既是博客,也是日记,里面记录了小狼的学习经历还有一些小狼的见解,非常希望每一个来到这里的人能够留下只言片语,更加的希望留下的是对于小狼的不足的补充,谢谢(*^__^*) 嘻嘻……”
原文地址:https://www.cnblogs.com/wolf-yasen/p/6618157.html