在牛客的寒假训练营里做到了一道组合博弈的题,在看了无数篇博客加自己的模拟后终于理解了SG函数的意义,特此来记录一下,当作是笔记。
SG函数理解
这里只是将个人对SG函数的理解记录一下,至于组合博弈的其他知识点就不在这里赘述了。
定义: SG(x)=mex(SG(y1),SG(y2),…) y为x的后继状态 mex表示没有出现过的最小的非负整数
就以众多教程里所用的取石子游戏为例吧。
有5个石子,每次可以取1,3,4个石子,两个人轮流取,如果到谁那石子取完了就算输。如果用SG(x)来表示输赢情况的话,当SG(x)==0时表示必输,否则必赢,至于为什么,在后面的例子里会作解释。
- 首先SG[0] = 0 没有石子的时候肯定输了
- SG[1] = mex( SG[0] ) = 1 这个状态必赢
- 再看SG[2] = mex( SG[1] ) = 0 这个状态必输 因为2只能到1 而1是必赢态,相对而言2就是必输态
- SG[3] = mex( SG[2], SG[0] ) = mex{ 0, 0 } = 1; 必赢 因为2是必输态
- SG[4] = mex{ SG[3], SG[1], SG[0] } = mex{ 1, 1, 0 } = 2; 必赢 因为0是必输态
- SG[5] = mex{ SG[4], SG[2], SG[1] } = mex{ 2, 0, 1 } = 3; 也是必赢 因为2是必输态
看完了上面的五个SG状态后能看出一点规律了,x必赢当且仅当x的后继状态中出现了必输态(SG(y)==0),因为后继状态的SG里有0,那么作mex运算就取不到0,因此SG(x)>0。 这也就是为什么要定义一个mex运算,就是为了判断后继状态里是否有0出现(其实不止这一个用处,在多个状态下可以异或运算来判断输赢情况)如果没有0出现,也就是后继状态全是必赢态,那么SG(x)就可以取到0,也就是x为必输态。
因此通过判断SG(x)是否等于0就可以知道x是输还是赢了。