题意
一个数串
A和B每人从这个数串的第一个或者最后一个元素选择一个数加到自己的得分里,A先选,求先手最大得分
样例:
4
-1 0 100 2
输出
99
分析
对于任意一个区间段 我们考虑的问题是相似的
不论任何区间段都是考虑取前面的还是取后面的
我们要从两种策略里选出一个更优的
对这个序列 我们每次都是从左或是从右选择一个元素拿出来
所以问题就相当于在从i到j的区间段里
如何表示两种策略那就是拿前面的和拿后面的计算结果
我们就把这个结果存到一个二维数组中
假设我们问题n==1
那么直接就能返回结果 得到最大先手
假设问题规模为2
那么就相当于选择左边的元素 那么对方的得分就是f(i+1,e)
先手得分就是sum[e]-sum[i-1]-f(i+1,e)
右边同理 我们选取两个中的那个最大的结果
当区间长度覆盖了全部区间段时就是我们要的结果
#include<bits/stdc++.h>
using namespace std;
int a[1010],f[1010][1010],sum[1010];
int main()
{int n;scanf("%d",&n);for(int i=1;i<=n;i++){scanf("%d",&a[i]);f[i][i]=a[i];sum[i]=sum[i-1]+a[i];}/*f[i][j]表示从i开始到j先手所能获取的最大值 */for(int i=2;i<=n;i++){for(int j=1;j<=n-i+1;j++){int e = j+i-1;f[j][e] = max(sum[e]-sum[j-1]-f[j+1][e],sum[e]-sum[j-1]-f[j][e-1]);}}printf("%d\n",f[1][n]);return 0;
}