zoukankan      html  css  js  c++  java
  • bzoj3895: 取石子(博弈论,记忆化搜索)

    3895: 取石子

    Time Limit: 1 Sec  Memory Limit: 512 MB
    Submit: 361  Solved: 177
    [Submit][Status][Discuss]

    Description

    Alice和Bob两个好朋含友又开始玩取石子了。游戏开始时,有N堆石子
    排成一排,然后他们轮流操作(Alice先手),每次操作时从下面的规则中任选一个:
    ·从某堆石子中取走一个
    ·合并任意两堆石子
    不能操作的人输。Alice想知道,她是否能有必胜策略。
     

    Input

    第一行输入T,表示数据组数。
    对于每组测试数据,第一行读入N。
    接下来N个正整数a1,a2…an,表示每堆石子的数量。
     

    Output

    对于每组测试数据,输出一行。
    输出YES表示Alice有必胜策略,输出NO表示Alice没有必胜策略。
     

    Sample Input

    3
    3
    1 1 2
    2
    3 4
    3
    2 3 5

    Sample Output

    YES
    NO
    NO

    HINT

    100%的数据满足T<=100,  N<=50. ai<=1000

    思路:

    本来想纯粹博弈论,结果发现最终有的情况数不确定,所以只能搜索一波

    因为无论何时,只要每堆都有石子,合并的结果都一样

    所以我们把每一堆石子都先取成1

    然后剩下这么多堆为1的石子,,每次操作有两种选择,要么合并,要么取走这一堆

    然后就结束了

    维护选用记忆化搜索

    代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define rii register int i
    using namespace std;
    int n,dp[55][50055],t,x,l,r,bj[55][50055];
    int dplast(int l,int r)
    {
        if(l==0)
        {
            return r&1;
        }
        if(r==1)
        {
            return dplast(l+1,0);
        }
        if(bj[l][r])
        {
            return dp[l][r];
            bj[l][r]=1;
        }
        if(l&&!dplast(l-1,r))
        {
            return dp[l][r]=1;
        }
        if(l&&r&&!dplast(l-1,r+1))
        {
            return dp[l][r]=1;
        }
        if(l>=2&&!dplast(l-2,r+2+(r?1:0)))
        {
            return dp[l][r]=1;
        }
        if(r&&!dplast(l,r-1))
        {
            return dp[l][r]=1;    
        }
        return dp[l][r]=0;
    }
    int main()
    {
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            l=0;
            r=-1;
            for(rii=1;i<=n;i++)
            {
                   scanf("%d",&x);
                  if(x==1)
                {
                    l++;
                   }
                   else
                {
                    r+=x+1;
                }
                if(r==-1)
                {
                    r=0;
                }
            }
            if(dplast(l,r)==1)
            {
                printf("YES
    ");
            }
            else
            {
                printf("NO
    ");
            }
        }
    }
  • 相关阅读:
    Vue知识总结
    Excel使用技巧
    java框架总结
    java反射学习总结
    java虚拟机
    vue学习知识
    mysql索引知识
    前端函数定义及表格总结
    SpringMVC异常处理
    restful风格的概念
  • 原文地址:https://www.cnblogs.com/ztz11/p/9405150.html
Copyright © 2011-2022 走看看