算法基础之集合-Nim游戏

集合-Nim游戏

  • 核心思想: 博弈论

    • sg函数:在有向图游戏中,对于每个节点x,设从x出发共有k条有向边,分别到达节点y1,y2,····yk,定义SG(x)的后记节点y1,y2,····,yk的SG函数值构成的集合在执行mex运算的结果,即:SG(x)=mex({SG(y1),SG(y2)····SG(yk)})
      **特别地,**整个有向图游戏G的SG函数值被定义为有向图游戏起点s的SG函数值,即 SG(G)=SG(s).
      • mex函数:设S表示一个非负整数集合.定义mex(S)为求出不属于集合S的最小非负整数运算
  •   #include <iostream>
      #include <cstring>
      #include <algorithm>
      #include <unordered_set>
      
      using namespace std;
      const int N = 110,M = 10010;
      
      int n,m;
      int s[N],f[M];
      
      int sg(int x)
      {
          if(f[x] != -1) return f[x];
          unordered_set<int> S;
          
          for(int i=0;i<m;i++)
          {
              int sum = s[i];
              if(x >= sum) S.insert(sg(x-sum));
          }
          
          for(int i=0;;i++)
              if(!S.count(i))
                  return f[x] = i;
      }
      int main()
      {
          cin>>m;
          for(int i=0;i<m;i++) cin>>s[i];
          cin>>n;
          memset(f,-1,sizeof f);
          
          int res=0;
          for(int i=0;i<n;i++)
          {
              int x;
              cin>>x;
              res ^= sg(x);
          }
          if (res) puts("Yes");
          else puts("No");
      }
    
  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阳光男孩01

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值