完全背包问题:
有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题再来。。。