• 一本通1668取石子


    1668:取石子

    时间限制: 1000 ms         内存限制: 524288 KB

    【题目描述】

    Alice 和 Bob 两个好朋友又开始玩取石子了。游戏开始时,有 NN 堆石子排成一排,然后他们轮流操作(Alice 先手),每次操作时从下面的规则中任选一个:

    1、从某堆石子中取走一个;

    2、合并任意两堆石子。

    不能操作的人输。Alice 想知道,她是否能有必胜策略。

    【输入】

    第一行输入 T,表示数据组数。

    对于每组测试数据,第一行读入 N;

    接下来 N 个正整数 a1,a2,,an,表示每堆石子的数量。

    【输出】

    对于每组测试数据,输出一行。

    输出 YES 表示 Alice 有必胜策略,输出 NO 表示 Alice 没有必胜策略。

    【输入样例】

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

    【输出样例】

    YES
    NO
    NO

    【提示】

    数据范围与提示:

    对于全部数据,T100,N50,ai1000

    sol:貌似和博弈论没有半毛钱关系

    如果没有1的堆,那么判断一下总操作数的奇偶性即可,烦就烦在有1,

    题解上说是记搜,分四种情况(具体见注释),不知道为什么n=50都能过qaq

    #include <bits/stdc++.h>
    using namespace std;
    typedef int ll;
    inline ll read()
    {
        ll s=0;
        bool f=0;
        char ch=' ';
        while(!isdigit(ch))
        {
            f|=(ch=='-'); ch=getchar();
        }
        while(isdigit(ch))
        {
            s=(s<<3)+(s<<1)+(ch^48); ch=getchar();
        }
        return (f)?(-s):(s);
    }
    #define R(x) x=read()
    inline void write(ll x)
    {
        if(x<0)
        {
            putchar('-'); x=-x;
        }
        if(x<10)
        {
            putchar(x+'0'); return;
        }
        write(x/10);
        putchar((x%10)+'0');
        return;
    }
    #define W(x) write(x),putchar(' ')
    #define Wl(x) write(x),putchar('
    ')
    const int N=55;
    int T;
    int n,A[N];
    int Bo[N][N*1000];
    inline bool dfs(int Num1,int Step)
    {
        if(Bo[Num1][Step]!=-1) return Bo[Num1][Step];
        if(Num1==0) return Bo[Num1][Step]=((Step&1)?1:0);
        if(Step==1) return Bo[Num1][Step]=dfs(Num1+1,0);
        if(Num1&&(!dfs(Num1-1,Step))) return Bo[Num1][Step]=1; //取走一个1
        if(Num1>=2&&(!dfs(Num1-2,Step+2+(Step?1:0)))) return Bo[Num1][Step]=1; //合并两个1
        if(Num1&&Step&&(!dfs(Num1-1,Step+1))) return Bo[Num1][Step]=1; //把一个1合并到非1堆中
        if(Step&&(!dfs(Num1,Step-1))) return Bo[Num1][Step]=1; //合并两个大堆或取走一个
        return Bo[Num1][Step]=0;
    }
    int main()
    {
        R(T);
        memset(Bo,-1,sizeof Bo);
        while(T--)
        {
            int i,Sum=-1,cnt=0;
            R(n);
            for(i=1;i<=n;i++)
            {
                A[i]=read();
                if(A[i]==1) cnt++;
                else Sum+=A[i]+1;
            }
            if(!cnt)
            {
                if(Sum&1) puts("YES");
                else puts("NO");
                continue;
            }
            Sum=max(Sum,0);
            if(dfs(cnt,Sum)) puts("YES");
            else puts("NO");
        }
        return 0;
    }
    /*
    input3
    5
    3
    2 1 3 
    4
    1 1 1 1 
    2
    1 3 
    5
    1 2 1 2 2 
    3
    1 1 1
    output
    YES
    YES
    YES
    NO
    NO
    */
    View Code
  • 相关阅读:
    解决js newDate()苹果手机日期格式显示NaN
    AD 用户个人信息补充
    CSV 文件批量导入 数据库 Pandas
    【笔记】单调栈?
    【其他】Modern C++ in OI
    【笔记】网络流
    【笔记】默认构造函数和零初始化
    【笔记】正确的当前弧优化
    golang读取文件的方法
    protobuf使用
  • 原文地址:https://www.cnblogs.com/gaojunonly1/p/10554797.html
Copyright © 2020-2023  润新知