首页 > 其他分享 >SG函数

SG函数

时间:2024-11-22 20:18:39浏览次数:1  
标签:状态 函数 异或 SG mex 必输 游戏

有向图游戏

题意:给定一个有向无环图,图中只有一个起点,在起点上放一个棋子,两个玩家轮流沿着有向边推动棋子,每次走一步,不能走的玩家失败

先分析一下

对于这样一个游戏,最终结束状态是棋子走到一个没有出度的点,这种状态属于必输状态,结合前两篇的 Nim 游戏可以知道,所有连向这个必输状态的状态都属于必赢状态,而没有后继状态或者后继状态都是必赢状态的状态则是必输状态

需要更严谨的理解与证明,先引入两个新东西

mex 运算

\(mex\) 运算是指对于一个集合,取集合中没有的最小非负整数
举个栗子
\(mex(0,1,2)=3\)
\(mex(1,2)=0\)

SG 函数

设当前状态 \(X\) 有后继状态 \(y_1 , y_2... y_k\)
而 \(SG(x) = mex(\small SG(y_1),SG(y_2),...,SG(y_k)\normalsize)\)

分析

现在有了这两个东西,那他是干什么用的呢

来进入刚刚分析的思路
考虑对于没有后记状态的节点,根据定义,它的 \(SG\) 值肯定是 \(0\),而对于它的前驱节点,\(SG\) 值就肯定非 \(0\) 了,而对于全部连着必胜状态的节点,\(SG\) 值就肯定又是 \(0\) 了
所以很明确,\(SG\) 值为 \(0\) 则代表这种状态为必输状态,否则则为必胜状态

那为什么不直接是 bool 类型的值呢?不是知道是否非 \(0\) 就行了吗?

NONONO!

假如一个有向图上,却有多个棋子,这个时候这个组合游戏又该如何判断呢?

注意,后文说的SG值异或和指的都是棋子所在点位的 \(SG\) 值异或和

还是先考虑最终的必输态,所有的棋子走到出度为 \(0\) 的必输点,每个 \(SG\) 值自然为 \(0\),所有 \(SG\) 值异或和自然也为 \(0\),考虑这样一件事,是否面对一个当前 \(SG\) 值异或和为 \(0\) 的局面一定会走向必输呢

考虑如果对手面对这样一种局面,对手无论进行怎样的操作,都会打破异或和为 \(0\) 的局面,因为一个 \(SG\) 值为 \(k\) 的节点,走向的后继节点 \(SG\) 值一定在 \(0\) 到 \(k-1\) 范围

忽然联想到什么,这和上上篇讲的取石子不完全一样吗,可以让当前这个 \(k\) 转变为 \(0\) 到 \(k-1\) 任意一个值

继续证明

现在到自己操作,自己也是一定可以将异或和非 \(0\) 的局面再次转变为 \(0\),理由同 Nim 游戏中那样,略过

不断的这样操作,终究会转变为最终的必输状态,并且此时轮到对手操作,所以,必胜

再回看那个联想,如果打个表会发现,对于 Nim 游戏的每个石堆的 \(SG\) 值,完全等于这个石堆的石子数量,所以,其实 Nim 游戏是 \(SG\) 函数的一种特例

后话

对于各种组合游戏,其实都本质相同,只是对于后继状态的转化各有不同罢了,博弈论还是颇有意思的,不过,咋想出来的异或和是组合游戏的结果哇

标签:状态,函数,异或,SG,mex,必输,游戏
From: https://www.cnblogs.com/hapihapi/p/18563675

相关文章

  • 字符函数和字符串函数
    字符函数例子 字符转换函数 strlen的实现和模拟  strcpy的使用和模拟         strcat的使用和模拟 strcmp的模拟和实现  ......
  • C语言字符串处理相关函数
    作用:处理字符串,如计算字符串长度,查找字符串中指定的字符或字符串,切割字符串等头文件:string.h相关函数:strlen作用:测量字符串长度语法:size_tstrlen(constchar*s);    参数:s:要测量的字符串的首地址    返回值:测量的字符串串长度注意:不包含......
  • Linux内核的spi_sync函数传输期间片选信号一直有效嘛?
         1、不是的,下图可以看到发送单个message时拉片选了,所以spi_sync函数传输期间CS会一直跳变,所以无法像I2C一样组装符合某个外设的报文队列。    2、但是使用自己的软件CS片选,就可以控制它在spi_sync函数传输期间保持低电平。    3、其中的某个使......
  • EXPORT_SYMBOL函数用法
    1、作用:EXPORT_SYMBOL()内定的函数或者符号对全部内核代码公开,不用修改内核代码就 可以在内核模块中直接调用,即使用EXPORT_SYMBOL()可以将一个函数导出给其他模块使用。 2、使用方法: 在模块函数定义之后使用“EXPORT_SYMBOL(函数名)”来声明; 在调用该函数的另外一个模块......
  • 写一个函数找出给定数组中的最大差值
    /***Findsthemaximumdifferencebetweenanytwoelementsinanarray.**@param{number[]}arrTheinputarrayofnumbers.*@returns{number}Themaximumdifference,or0ifthearrayisemptyorhasonlyoneelement.*/functionfindMaxDifferen......
  • 请写出一个函数求出N的阶乘(即N!)
    /***Calculatesthefactorialofanon-negativeinteger.**@param{number}nThenon-negativeinteger.*@returns{number}Thefactorialofn,or1ifnis0.*Returns-1ifnisnegativeornotaninteger.*/functionfactori......
  • 入门RTOS第七篇(队列函数)
    1.使用队列的流程:创建队列,写队列,读队列,删除队列2.创建队列有两种方法:动态分配内存、静态分配内存函数原型如下:QueueHandle_txQueueCreate(UBaseType_tuxQueueLength,UBaseType_tuxItemSize);静态分配内存:xQueueCreateStatic,队列的内存要事先分配好函数原型如下:Qu......
  • 函数栈帧的创建和销毁(未完待续)
    文章目录一、什么是函数栈帧二、函数栈帧到底能解决什么呢?三、函数栈帧的创建和销毁解析过程(太详细了)1.栈?是神麽2.认识相关寄存器和汇编指令(太多辣)3.解析函数栈帧的创建和销毁3.1预备3.2再准备(函数的调用堆栈)3.4准备2(调整环境)3.5准备3(转到反汇编)3.6函数栈帧的创建(终于......
  • python中math 模块函数及其用法
    在Python中,math模块提供了许多数学函数和常量,适用于各种数学计算。以下是math模块的语法、常用函数以及使用注意事项的详细讲解。1.导入math模块在使用math模块之前,必须先导入它:importmath2.常用函数以下是一些常用的math模块函数及其用法:数学常量math.p......
  • 用函数实现:在字符串str中找出ASCII码值最大的字符,将其放在第一个位置上;并将该字符前的
    完整的题目在这里哈:用函数实现:在字符串str中找出ASCII码值最大的字符,将其放在第一个位置上;并将该字符前的原字符向后顺序移动。要求字符串str只包含数字、大写或小写字母。例如,调用fun_delet()函数之前给字符串输入:ABCDeFGH,调用后字符串中的内容为:eABCDFGH.     时......