动规——【USACO3.3.5】A Game游戏 IOI'96

Description

有如下一个双人游戏:N(2 <= N <= 100)个正整数的序列放在一个游戏平台上,游戏由玩家1开始,两人轮流从序列的两端取数,取数后该数字被去掉并累加到本玩家的得分中,当数取尽时,游戏结束。以最终得分多者为胜。 

编一个执行最优策略的程序,最优策略就是使玩家在与最好的对手对弈时,能得到的在当前情况下最大的可能的总分的策略。你的程序要始终为第二位玩家执行最优策略。 

状态:f[i][j]表示第i个数到第j个数先手可以获得的最大得分。

决策:先手可以取第i个数,那么剩下的i+1到j个数就等价于后手的情况,反之亦然。

代码如下:

#include<cstdio>
#include<iostream>
using namespace std;
int s[105],f[105][105],sum[105];
int main(){
int i,n,j;
scanf("%d",&n);
for(i=1;i<=n;i++){
  scanf("%d",&s[i]);
  sum[i]=sum[i-1]+s[i];     //求前缀和
  f[i][i]=s[i]; 
}
for(i=n;i>0;i--)     //倒序枚举
  for(j=i+1;j<=n;j++)
    f[i][j]=max(sum[j]-sum[i]-f[i+1][j]+s[i],sum[j-1]-sum[i-1]-f[i][j-1]+s[j]);
printf("%d %d",f[1][n],sum[n]-f[1][n]);
}


你可能感兴趣的:(动规——【USACO3.3.5】A Game游戏 IOI'96)