博弈之nyoj 970 Yougth's Game II 题解

Yougth's Game II

时间限制: 1000 ms  |  内存限制: 65535 KB
难度: 2
描述

CET4的成绩出来了,Yougth考的很惨,为了调整心情,它决定去找CET4过了的Hrdv同学PK,当然作为一个有涵养的人,不能动不动就动手,于是他想了一个游戏和Hrdv去玩。

游戏是这样,由第三方任意给定k(1<=k<=100)个数字a1,a2,a3...ak,一开始,有x(1<=k<=10^4)枚硬币,Yougth和Hrdv轮流取硬币。每次取的硬币的枚数一定要在a1,a2,a3...ak当中。Yougth先取,还是老规矩,取走最后一枚硬币的一方获胜,而双方都非常聪明,采取最优策略,谁会获胜?

输入
多组测试数据,第一行两个数x和k
第二行是k个数a1,a2,a3...ak,为简化题目难度,k个数中一定有1.
输出
如果Yougth获胜输出“Wa,Yougth is Best!”
如果Hrdv获胜输出“Oh,Sorry!Yougth Lost!”
样例输入
9 2
1 4
10 2
1 4
样例输出
Wa,Yougth is Best!
Oh,Sorry!Yougth Lost!

题解报告

Yougth's Game II

这道题目是一道博弈题目,可以根据之前的分析博弈的方法进行分析。

首先Yougth先取,谁取完则获胜,那么谁如果面对当前有0个的局面则是必输点。

k个数中的a1,a2,a3...ak则是先手的第一个必胜点。

推理发现必胜点加k个数中任意一个为必输点,而必输点加k个数中任意一个为必胜点。

所以对于任意一点x点。其胜负由(x-ai)决定。可以先出示x为先手必输点。假如他满足有任意一个x-ai是必输点的话,那么它一定是必胜点。

由此可得出答案,代码详见:

 
 #include <cstdio>
#include <cstring>
int a[110];
bool ans[11000];
int main()
{
    int k,n;
    while(~scanf("%d%d",&n,&k))
    {
        for(int i=0;i<k;i++)
            scanf("%d",&a[i]);
        memset(ans,false,sizeof(ans));
        for(int i=1;i<=n;i++)
        {
            for(int j=0;j<k;j++)
            {
                ans[i] |= a[j]<=i&&!ans[i-a[j]];
            }
        }
        printf(ans[n]?"Wa,Yougth is Best!\n":"Oh,Sorry!Yougth Lost!\n");
    }
    return 0;
}        


你可能感兴趣的:(游戏,printf,动态规划,博弈,amp)