题意:有一个长度为n的序列,a,b轮流从两边取数,a先取,可以一次取多个,但要是同一边,得分为所取数值和,问在a,b都采取最优策略下,a得分减去b的结果。
状态转移:d[i,j]=sum[i.j]-min{d[i+1,j],d[i+2,j]......d[i,j-1],d[i,j-2]......0}
d[i,j]表示地i~j中,根据提议的取法,先取的得分的最大值。
#include<iostream>
using namespace std;
const int maxn=110;
int a[maxn];
int sum[maxn];
int dp[maxn][maxn];
int g[maxn][maxn],f[maxn][maxn];
void fun(int n)
{
for(int i=1;i<=n;i++)
f[i][i]=g[i][i]=dp[i][i]=a[i];
for(int i=1;i<=n;i++)
{
for(int j=1;j+i<=n;j++)
{
int k=i+j;
int m=0;
m=min(m,f[j+1][k]);
m=min(m,g[j][k-1]);
dp[j][k]=sum[k]-sum[j-1]-m;
f[j][k]=min(dp[j][k],f[j+1][k]);
g[j][k]=min(dp[j][k],g[j][k-1]);
}
}
cout<<2*dp[1][n]-sum[n]<<endl;
}
int main()
{
int n;
while(cin>>n,n)
{
sum[0]=0;
for(int i=1;i<=n;i++)
{
cin>>a[i];
sum[i]=sum[i-1]+a[i];
}
fun(n);
}
return 0;
}