Daizhenyang's Coin HDU - 3537

本文探讨了博弈论中的一种特殊应用——SG函数在解决硬币翻转游戏问题上的策略。通过分析硬币正反面排列的组合博弈,文章详细解释了如何利用SG函数确定游戏的最优策略,以及如何通过硬币位置的二进制表示判断SG函数值,最终得出游戏胜负的关键。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Daizhenyang’s Coin HDU - 3537

题意: 若干个个硬币排成一排,其中有n个是正的,其它都是反的,每一次你可以选择1,2,3 个进行反转,但是最右边的硬币必须是从正面到反面
SG函数可以用来求组合博弈问题

  1. 博弈的人数是两个
  2. 有限步内结束
  3. 每个状态的胜负与人无关

本题是Game theory 论文里面例题
首先由x1,x2,x3 位置的硬币为正,那么他们满足 S G ( x 1 , x 2 , x 3 ) = S g ( x 1 ) ⊕ S G ( x 2 ) ⊕ S G ( x 3 ) SG(x_1,x_2,x_3) = Sg(x_1 )\oplus SG(x_2) \oplus SG(x_3) SG(x1,x2,x3)=Sg(x1)SG(x2)SG(x3)

怎么求SG(x) 的值呢
经过打表发现SG(x) 的函数值不是2x+1,就是2x,这个规律是什么呢?

position x : 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 ...
g(x) : 		 1 2 4 7 8 11 13 14 16 19 21 22 25 26 28 ... 

定义两个数,暂且称之为 O( odious ),E(evil),
O: 代表x的二进制表达里面有奇数个1
E: 代表x的二进制表达里面有偶数个1

有一些特殊的库函数用G++编译的时候支持以下操作
__builtin_parity(a) 直接返回a的二进制表达中1的个数的奇偶性,如果有奇数个,返回1,否则返回0

O,E有以下运算法则
O ⊕ O = E , E ⊕ E = E O \oplus O = E,E \oplus E = E OO=E,EE=E
O ⊕ E = O , E ⊕ O = O O \oplus E = O, E \oplus O = O OE=O,EO=O
我们发现SG(x) 的值是第x个O数
结论如下:

  1. 如果2 * x是O数,SG函数值为2*x
  2. 如果2 * x是E数, SG函数值是2*x+1

证明:

没有硬币是正的,终止态,SG = 0,是E数
最左边的硬币(位置从0开始)是的正的 S G ( 0 ) = 1 SG(0)= 1 SG(0=1,是O数
假设对于前x的个数满足证明,对于第x个数的SG值
选择反转一个硬币到终止态SG(0) = 0
选择反转两个硬币,则可以转移到 S G ( 1 ) , S G ( 2 ) , S G ( 3 ) . . . . . . S G ( x − 1 ) SG(1),SG(2),SG(3)......SG(x-1) SG(1),SG(2),SG(3)......SG(x1),是小于2x的所有O数
选择反转三个硬币,是 S G ( i ) ⊕ S G ( j ) i ! = j i , j &lt; x SG(i)\oplus SG(j) \quad i != j \quad i ,j &lt; x SG(i)SG(j)i!=ji,j<x,是小于等于2
x的所有E数
所以有结论

  1. 如果2 * x是O数,SG函数值为2*x
  2. 如果2 * x是E数, SG函数值是2*x+1

参考代码


int main(void)
{
   int n;
   while(cin>>n){
      int sum = 0;
      map<int,int> ma;
      for(int i = 0;i < n; ++i){
         int a;
         scanf("%d",&a);
         if(ma[a]) continue;
         ma[a] = 1;
         if(__builtin_parity(2*a))
            sum ^= 2*a;
         else
            sum ^= 2*a+1;
      }
      if(sum == 0)
         puts("Yes");
      else
         puts("No");
   }
    

   return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值