Game of Sum

可以知道整体石子的总和一定的,所以一个人的得分越高,另一个人的得分就越低。不管怎么取任意时刻游戏的状态都是原始序列的一段连续子序列(即被玩家取剩下的序列)。

因此,用d(i,j)表示玩家A在i到j部分的最大和,在双方都采取最优策略的情况下,先手得分最大值。

d[i][j] = sum[i][j] - min(dp(i + k, j), dp(i, j - k)); (1 <= k <= j - i + 1)

#include<stdio.h>
#include<stdlib.h>
#include<algorithm>
#include<string.h>
using namespace std;
int S[105], A[105], d[105][105], vis[105][105], n;
int dp(int i, int j) 
{
    if (vis[i][j]) 
        return d[i][j];
    vis[i][j] = 1;
    int m = 0;
    for (int k=i+1;k<=j;k++) 
    {
        m=min(m,dp(k,j));
    }
    for(int k=i;k<j;k++)
    {
        m=min(m,dp(i,k));
    }
    d[i][j]=S[j]-S[i-1]-m;
    return d[i][j];
}
int main() 
{
    while (scanf("%d", &n), n) 
    {
        memset(vis, 0, sizeof(vis));
        S[0]=0;
        for(int i=1;i<=n;i++) 
        {
            scanf("%d", &A[i]);
            S[i]=S[i-1]+A[i];
        }
        printf("%d\n",2*dp(1,n)-S[n]); //dp(1, n) - (S[n] - dp(1, n))
    }
    return 0;
}

  

posted @ 2017-12-04 23:44  山水有相逢  阅读(221)  评论(0编辑  收藏  举报