游戏
使用博弈论,f[i][j]代表移动这方和对方分值的最大差值(其实就是yxc说的先手和后手,但是老师讲得先手后手是一直在变的,所以我觉得用此时移动的一方来指代会更清晰一点)。
可以推出状态计算:f[i][j]=max(w[i]-f[i+1][j],w[j]-f[i][j-1]);(为什么用减法:因为f[i+1][j]和f[i][j-1]都是下一轮移动方(设为B)-下一轮不动方(设为A)的最大差值,那么这一轮移动方和不动方互换,A-B的差值就是-f[i+1][j]或-f[i][j-1],加上w[i]或w[j]后取max就是这一轮移动方(A)-不动方(B)的最大差值)
可以计算出第一轮中A(玩家一.移动方)-B(玩家二.不动方)的最大差值为f[1][n],即已知A-B的值,又知道A+B的值,就可以列方程分别计算出A和B的值。
#include<bits/stdc++.h>
using namespace std;
#define N 110
int f[N][N],w[N];
int main()
{
int n,sum=0;
cin>>n;
for(int i=1;i<=n;i++) cin>>w[i],f[i][i]=w[i],sum+=w[i];
for(int l=2;l<=n;l++)//长度
{
for(int i=1;i<=n-l+1;i++)//起点
{
int j=i+l-1;//终点
f[i][j]=max(w[i]-f[i+1][j],w[j]-f[i][j-1]);
}
}
int d=f[1][n];//第一轮A-B的最大差值为f[1][n];又因为已知A+B=sum,所以可以解方程求出A,B的分值
cout<<(sum+d)/2<<' '<<(sum-d)/2<<endl;
}