【题意】:给出一个序列有n个元素,按左到右可以选出一些元素,如果当前元素在偶数次选取则得到该分数,否则扣去该分数,可以跳过一些元素不选,问最后可以得到的最大分数为多少。

【题解】:刚开始想到了O(n)的做法,后来又被自己推翻了,最后经过仔细思考发现之前的想法是对的。
              状态:
                  dp[i][0] 表示已经考虑了前i个元素,且已经拿了奇数个元素的最大分数
                  dp[i][1] 表示已经考虑了前i个元素,且已经拿了偶数个元素的最大分数
              转移:
                  dp[i][0] = max(dp[i-1][0], dp[i-1][1] - val[i]);
                  dp[i][1] = max(dp[i-1][1], dp[i-1][0] + val[i]);

【代码】:
 1 #include "iostream"
 2 #include "cstdio"
 3 #include "cstring"
 4 using namespace std;
 5 #define maxn 150500
 6 int dp[maxn][2];
 7 int val[maxn];
 8 int n;
 9 int solve() {
10     dp[0][0= dp[0][1= 0;
11     for(int i = 1; i <= n; i++) {
12         dp[i][0= max(dp[i-1][0], dp[i-1][1- val[i]);
13         dp[i][1= max(dp[i-1][1], dp[i-1][0+ val[i]);
14     }
15     return max(dp[n][0], dp[n][1]);
16 }
17 
18 int main() {
19     while(~scanf("%d"&n)) {
20         for(int i = 1; i <= n; i++) scanf("%d"&val[i]);
21         int ans = solve();
22         cout << ans << endl;
23     }
24     return 0;
25 }