参考:刘汝佳大白书p67-p69
整数的总和是一定的,所以一个人得分越高,另一个人的得分越低。
不管任意时刻游戏的状态都是原始序列的一段连续子序列,(因而可用区间dp)
//#pragma warning (disable: 4786)
//#pragma comment (linker, "/STACK:16777216")
//HEAD
#include <cstdio>
#include <ctime>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <map>
#include <cmath>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
//LOOP
#define FE(i, a, b) for(int i = (a); i <= (b); ++i)
#define FED(i, b, a) for(int i = (b); i>= (a); --i)
#define REP(i, N) for(int i = 0; i < (N); ++i)
#define CLR(A,value) memset(A,value,sizeof(A))
#define CPY(a, b) memcpy(a, b, sizeof(a))
#define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
//INPUT
#define RI(n) scanf("%d", &n)
#define RII(n, m) scanf("%d%d", &n, &m)
#define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
#define RS(s) scanf("%s", s)
//OUTPUT
#define WI(n) printf("%d\n", n)
#define WS(s) printf("%s\n", s)
typedef long long LL;
const int INF = 1000000007;
const double eps = 1e-10;
const int MAXN = 110;
int n, dp[MAXN][MAXN];
int a[MAXN];
int sum[MAXN];
bool vis[MAXN][MAXN];
int Left[MAXN][MAXN], Right[MAXN][MAXN];
//(1)n^3
//int dpf(int l, int r)
//{
// if (l == r) return a[l];
// if (vis[l][r]) return dp[l][r];
// vis[l][r] = true;
// int &ans = dp[l][r];
// ans = sum[r] - sum[l - 1];
// FE(i, l, r - 1)
// {
ans = max(ans, sum[i] - sum[l - 1] + sum[r] - sum[i] - dpf(i + 1, r));
// ans = max(ans, sum[r] - sum[l - 1] - dpf(i + 1, r));
// }
// FED(i, r, l + 1)
// {
ans = max(ans, sum[r] - sum[i - 1] + sum[i - 1] - sum[l - 1] - dpf(l, i - 1));
// ans = max(ans, sum[r] - sum[l - 1] - dpf(l, i - 1));
// }
//
// return ans;
//}
//(2)n^3
//int dpf(int l, int r)
//{
// if (l == r) return a[l];
// if (vis[l][r]) return dp[l][r];
// vis[l][r] = true;
// int tmp = 0;
//
// FE(i, l, r - 1)
// {
// tmp = min(tmp, dpf(i + 1, r));
// }
// FED(i, r, l + 1)
// {
// tmp = min(tmp, dpf(l, i - 1));
// }
// dp[l][r] = sum[r] - sum[l - 1] - tmp;
// return dp[l][r];
//}
//(3)n^2
int solve()
{
FE(i, 1, n)
{
Left[i][i] = Right[i][i] = dp[i][i] = a[i];
}
for (int L = 1; L < n; L++)///长度
{
for (int i = 1; i + L <= n; i++)
{
int j = i + L;///区间为[i, j]
int tmp = 0;
tmp = min(tmp, Left[i + 1][j]);
tmp = min(tmp, Right[i][j - 1]);
dp[i][j] = sum[j] - sum[i - 1] - tmp;
Left[i][j] = min(dp[i][j], Left[i + 1][j]);
Right[i][j] = min(dp[i][j], Right[i][j - 1]);
}
}
return dp[1][n];
}
int main ()
{
while (~RI(n) && n)
{
sum[0] = 0;
FE(i, 1, n)
{
RI(a[i]);
sum[i] = sum[i - 1] + a[i];
}
printf("%d\n", solve() * 2 - sum[n]);
// CLR(vis, 0);
// printf("%d\n", dpf(1, n) * 2 - sum[n]);
}
return 0;
}