思路:
for (int i = 1; i <= b - a; i++)
ans = max(ans, sum[b] - sum[a] - min(f(a + i, b), f(a, b - i)));
return dp[a][b] = ans;
上述代码的dp[a][b]存储的是当数字剩为a~b段时,某人(可以是A,也可以是B)所能取数字的最佳和值,
sum[i]用前缀数组记录数字和值,
那么,作为一方,你能取的最大值就是这段总和减去对方所能取的最小值。
完整代码:
/*0.069s*/
#include<bits/stdc++.h>
using namespace std;
const int N = 105;
int n, dp[N][N], num[N], sum[N];
bool vis[N][N];
int f(int a, int b)
{
if (a >= b) return 0;
if (vis[a][b]) return dp[a][b];
vis[a][b] = true;
int ans = -INT_MAX, len = b - a;
for (int i = 1; i <= len; i++)
ans = max(ans, sum[b] - sum[a] - min(f(a + i, b), f(a, b - i)));
return dp[a][b] = ans;
}
int main()
{
while (scanf("%d", &n), n)
{
memset(dp, 0, sizeof(dp));
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++)
{
scanf("%d", &num[i]);
sum[i] = sum[i - 1] + num[i];///前缀数组
}
printf("%d\n", f(0, n) * 2 - sum[n]);
}
return 0;
}