水水更健康。。。话说蒟蒻的noip爆炸了怎么办?←_←

这道题裸的区间dp:

f[i, j]表示当前取全了i到j之间的金币,最大值为多少

于是f[i, j] = sum[i, j] - min(f[i + 1, j], f[i, j - 1])

但是卡空间。。

于是改一下方程:

令len = j - i + 1,则

f[i, len]表示当前取全了i到i + len - 1之间的金币,最大值为多少

len从1开始向上枚举,于是第二维就可以压掉了。

然后就没有然后了= =

 

 1 /**************************************************************
 2     Problem: 2101
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:100 ms
 7     Memory:844 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <cctype>
12 #include <algorithm>
13  
14 using namespace std;
15 const int N = 5005;
16  
17 int s[N], f[N];
18 int n;
19  
20 inline int read(){
21     int x = 0;
22     char ch = getchar();
23     while (!isdigit(ch))
24         ch = getchar();
25     while (isdigit(ch)){
26         x = x * 10 + ch - '0';
27         ch = getchar();
28     }
29     return x;
30 }
31  
32 int main() {
33     n = read();
34     int i, len;
35     for (i = 1; i <= n; ++i) {
36         f[i] = read();
37         s[i] = s[i - 1] + f[i];
38     }
39     for (len = 1; len < n; ++len)
40         for (i = 1; i <= n - len; ++i)
41             f[i] = s[i + len] - s[i - 1] - min(f[i], f[i + 1]);
42     printf("%d\n", f[1]);
43     return 0;
View Code

 

posted on 2014-11-15 18:49  Xs酱~  阅读(171)  评论(0编辑  收藏  举报