1279 石子取数

 
描述

这是一个很古老的游戏,现在有n 堆石子排成一排,第 i 堆石子的数量为 ai, 两个人轮流取石子,每次只能从两边的石子中取走一堆且必需取走一堆。直到把n 堆石子都取完,取到较多石子的一方获胜。

Lqs 和 yuki 正在饶有趣味的玩着这个游戏: 对于一线ACM 队员来说,他们在玩游戏的时候自然都采用了最优策略,也就是说其实在n 堆石子的数量给定的时候,结果也已经确定了。。。

输入

第一行为一个整数T,表示有T组测试数据

对于每组测试数据,第一行一个整数n (n <= 100) ,即石子的堆数,接下来有n 个整数,第 i 个整数表示第 i 堆石子的数量。

输出

对于每组测试数据输出一行,两个用空格隔开的整数,依次为玩家一(先取的玩家)和玩家二(后取的玩家)所获得的石子数。

样例输入
2
4
1 2 3 4
4
1 3 4 2
样例输出
6 4
5 5

 

动态规划

#include <stdio.h>
#include<stdlib.h>
#include<string.h>
int f[101][101],s[101][101];
int n;
int num[101];
int max(int a, int b)
{
	return a>b?a:b;
} 
int search(int i,int j)
{
    if(f[i][j]>=0) 
		return f[i][j];
    return f[i][j]=max(num[i]+s[i+1][j]-search(i+1,j),num[j]+s[i][j-1]-search(i,j-1));
}
void work()
{ 
	int i,j;
    memset(f,-1,sizeof(f));
    memset(s,0,sizeof(s));
   
    for(i=1;i<=n;i++) s[i][i]=f[i][i]=num[i];
    for(i=1;i<=n;i++)
    {
        for(j=i+1;j<=n;j++)
        {
            s[i][j]=s[i][j-1]+num[j];
        }
    }
    search(1,n);
	printf("%d %d\n",f[1][n],s[1][n]-f[1][n]);
}
int main()
{
    int T,i;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&n);
        for( i=1;i<=n;i++)
        {
            scanf("%d",&num[i]);
        }
        work();
    }
    return 0;
}


 

你可能感兴趣的:(游戏,测试,search)