用 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;
}