http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=3566
这有点像背包问题,我没研究过。反正我是这样做的:dp[w]中存的是重量w下最大的v,我没有从dp[w-1]推到dp[w]这样状态转移,
我只是从每次加一个重量时,去处理(用了insertValue函数)。其实,1,2,3三种情况我都把它转化成在原来的dp[]中插入w1,v1,w2
,v2,其中第一种就是(w1+w2, v1+v2), (w1, 0), (w2, 0)三种情况,把他们的值存入t[]中,然后取最大的最后放入dp[]中;那么第二种
就是(w1,v1), (w2,v2)两种情况的筛选;第三种就是(w1,v1),(w1 + w2, v1 + v2);
最后遍历一遍,最大的值就是答案。
1 #include <iostream> 2 #include <stdlib.h> 3 #include <string> 4 #include <cstring> 5 using namespace std; 6 int N ; 7 int t[50001]; 8 int dp[50001]; 9 void insertValue(int w1, int v1, int w2, int v2) 10 { 11 int i, j; 12 memset(t, -1, sizeof t); 13 for(i = 0; i < N; i ++) 14 if(dp[i] != -1 && i + w1 < N) 15 t[i+w1] = dp[i] + v1; 16 if(v2 != 0) 17 { 18 for(i = 0; i < N; i ++) 19 { 20 if(dp[i] != -1 && i + w2 < N) 21 { 22 int temp = v2 + dp[i]; 23 t[w2+i] = temp > t[w2+i] ? temp : t[w2+i]; 24 } 25 } 26 } 27 for(i = 0; i < N; i ++) 28 dp[i] = t[i] > dp[i] ? t[i] : dp[i]; 29 } 30 int main() 31 { 32 int total, num; 33 int i, j; 34 int w1, v1, w2, v2, t; 35 while(cin >> total >> num) 36 { 37 total /= 100; 38 N = total + 5; 39 memset(dp, -1, sizeof dp); 40 dp[0] = 0; 41 for(i = 0; i < num; i ++) 42 { 43 cin >> w1 >> v1 >> w2 >> v2 >> t; 44 w1 /= 100; 45 w2 /= 100; 46 if(t == 1) 47 { 48 w1 += w2; 49 v1 += v2; 50 v2 = 0; 51 } 52 else if(t == 3) 53 { 54 w2 += w1; 55 v2 += v1; 56 } 57 insertValue(w1, v1, w2, v2); 58 } 59 int max = -1; 60 for(i = 0; i <= total; i ++) 61 max = max > dp[i] ? max : dp[i]; 62 cout << max << endl; 63 } 64 return 0; 65 }