【題意】:給出一個(gè)序列有n個(gè)元素,按左到右可以選出一些元素,如果當(dāng)前元素在偶數(shù)次選取則得到該分?jǐn)?shù),否則扣去該分?jǐn)?shù),可以跳過(guò)一些元素不選,問(wèn)最后可以得到的最大分?jǐn)?shù)為多少。

【題解】:剛開(kāi)始想到了O(n)的做法,后來(lái)又被自己推翻了,最后經(jīng)過(guò)仔細(xì)思考發(fā)現(xiàn)之前的想法是對(duì)的。
              狀態(tài):
                  dp[i][0] 表示已經(jīng)考慮了前i個(gè)元素,且已經(jīng)拿了奇數(shù)個(gè)元素的最大分?jǐn)?shù)
                  dp[i][1] 表示已經(jīng)考慮了前i個(gè)元素,且已經(jīng)拿了偶數(shù)個(gè)元素的最大分?jǐn)?shù)
              轉(zhuǎn)移:
                  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 }