UVA

来源:互联网 发布:淘宝游戏光盘 编辑:程序博客网 时间:2024/06/10 13:58

用 dp[ i ] [ j ] 表示 i - j 区间内某个人能取的最大值
具体转移过程的理解见题解中

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<math.h>#include<set>#include<stack>#include<queue>#include<ctype.h>#include<vector>#include<algorithm>#define PI acos(-1.0)// cout << "  ===  " << endl;using namespace std;typedef long long ll;const int maxn = 10000 + 7, INF = 0x3f3f3f3f, mod = 1e9+7;int n;int a[maxn], sum[maxn], dp[maxn][maxn], vis[maxn][maxn];void init() {    memset(sum, 0, sizeof sum);    memset(vis, 0, sizeof vis);    for(int i = 1; i <= n; ++i) {        scanf("%d", &a[i]);        sum[i] = sum[i-1] + a[i];    }}int d(int l, int r) { // 区间 l - r 之间某个人能取的最大值    if(vis[l][r]) return dp[l][r];    vis[l][r] = 1;    int min_ = 0;     //记录从左右两边开始的子区间的最小值(负的),那么这个区间的最大值就是区间和减去这个最小值;如果是正的,那么整个区间的和就是这个区间的最大值    for(int i = l; i < r; ++i)        min_ = min(min_, d(l, i));    for(int i = l+1; i <= r; ++i)        min_ = min(min_, d(i, r));    return dp[l][r] = (sum[r] - sum[l-1] - min_ );}int main() {    while(scanf("%d", &n) != EOF && n) {        init();        printf("%d\n", d(1, n) * 2 - sum[n]);    }    return 0;}
原创粉丝点击