思路:
双方每次都会选对自己未来最优的。
用一个二维数组储存(i,j)上的最优值,每次询问枚举右边界、左边界,返回最大值。
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef vector<int> vi;
typedef vector<vi> vii;
typedef vector<ll> vll;
const int MAXN = 1e6 + 10;
const ll INF = 0x3f3f3f3f;
const ll MOD = 1e9 + 7;
const double eps = 1e-8;
int n, m, k;
vi p, sum;
vii dp, vis;
int recur(int u, int v){
if(u > v)
return 0;
if(vis[u][v])
return dp[u][v];
vis[u][v] = 1;
for(int i = u; i <= v; i++)
dp[u][v] = max(dp[u][v], sum[i] - sum[u - 1] - recur(i + 1, v));
for(int i = v; i >= u; i--)
dp[u][v] = max(dp[u][v], sum[v] - sum[i - 1] - recur(u, i - 1));
return dp[u][v];
}
int main(void)
{
ios::sync_with_stdio(false);
cin.tie(0);
cout << setprecision(10) << fixed;
while(cin >> n, n){
p.clear();
p.resize(n + 1);
sum.clear();
sum.resize(n + 1);
dp.clear();
dp.resize(n + 1, vi(n + 1, -INF));
vis.clear();
vis.resize(n + 1, vi(n + 1));
for(int i = 1; i <= n; i++)
cin >> p[i];
for(int i = 1; i <= n; i++)
sum[i] = sum[i - 1] + p[i];
cout << recur(1, n) << endl;
}
cerr << "execute time : " << (double)clock() / CLOCKS_PER_SEC << endl;
return 0;
}