因为A和B都是足够聪明的,所以他们都会选择最优的解,就是让自己的得分更大,那么,就是说让对手的分更少,d[i][j]表示在i到j这些数里面在左边取或者在右边取所能得到的最大的值,然后每次取的尽量是让对手所能取的d[i][j]是最小的,方程如下
d[i][j]=sum[j]-sum[i-1]-min( min(d[i+1][j],d[i+2][j],…… ),min( d[j][j-1],d[j][j-2],…… )
记忆化搜索
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
int sum[105];
int array[105];
int visited[105][105];
int d[105][105];
int n;
int sss;
int dp(int left,int right){
int i;
if(visited[left][right])
return d[left][right];
int m=0;
for(i=1;i<=right-left;i++){
m=min(dp(left+i,right),m);
m=min(dp(left,right-i),m);
}
d[left][right]=sum[right]-sum[left-1]-m;
visited[left][right]=1;
return d[left][right];
}
int main(){
int i,j;
while(scanf("%d",&n)){
if(n==0){
break;
}
memset(visited,0,sizeof(visited));
memset(d,0,sizeof(d));
sum[0]=0;
for(i=1;i<=n;i++){
scanf("%d",&array[i]);
sum[i]=sum[i-1]+array[i];
}
printf("%d\n",2*dp(1,n)-sum[n]);
}
return 0;
}
递推
#include <cstdio>
#include <algorithm>
using namespace std;
int main(){
int i,j;
int n;
int array[105];
int sum[105];
int f[105][105];
int g[105][105];
int d[105][105];
while(scanf("%d",&n)&&n){
sum[0]=0;
for(i=1;i<=n;i++){
scanf("%d",&array[i]);
sum[i]=sum[i-1]+array[i];
f[i][i]=array[i];
g[i][i]=array[i];
d[i][i]=array[i];
}
int i,j;
for(int l=1;l<n;l++){
for(i=1;i<n;i++){
j=i+l;
int m=0;
m=min(min(f[i+1][j],g[i][j-1]),m);
d[i][j]=sum[j]-sum[i-1]-m;
f[i][j]=min(d[i][j],f[i+1][j]);
g[i][j]=min(d[i][j],g[i][j-1]);
}
}
printf("%d\n",2*d[1][n]-sum[n]);
}
return 0;
}