vijos 1037 ***

链接:点我

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 using namespace std;
 6 const int v = 2000 + 5;
 7 const int MaxN = 100 + 5;
 8 int N, sum, num[MaxN], dp[2][v];
 9 int main() {
10     int i, j, k;
11     cin >> N;
12     for(i = 0; i < N; ++i) {
13         cin >> num[i];
14         sum += num[i];
15     }
16     memset(dp, -1, sizeof(dp));
17     dp[1][0] = 0;
18     int a;
19     for(i = 0; i < N; ++i) {
20         a = i % 2;
21         memset(dp[a], -1, sizeof(dp[a]));
22         for(j = 0; j <= sum; ++j) {
23             //1.不放第i块水晶;
24             if(dp[a ^ 1][j] > -1)
25                 dp[a][j] = dp[a ^ 1][j];
26             //2.放进去后,高塔变矮塔(第i块放在矮塔上了);
27             if(num[i] > j &&  dp[a ^ 1][num[i] - j] > -1)
28                 dp[a][j] = max(dp[a][j], dp[a ^ 1][num[i] - j] + j);
29             //3.放进去后,高塔仍高(第i块放在矮塔上);
30             if(j + num[i] <= sum && dp[a ^ 1][j + num[i]] > -1)
31                 dp[a][j] = max(dp[a][j], dp[a ^ 1][j + num[i]]);
32             //4.放进去后,高塔更高(第i块放在高塔上).
33             if(j >= num[i] && dp[a ^ 1][j - num[i]] > -1)
34                 dp[a][j] = max(dp[a][j], dp[a ^ 1][j - num[i]] + num[i]);
35         }
36     }
37     if(dp[a][0] > 0)
38         cout << dp[a][0] << endl;
39     else
40         cout << "Impossible" << endl;
41 }
原文地址:https://www.cnblogs.com/cnblogs321114287/p/4638345.html