zoukankan      html  css  js  c++  java
  • SG函数

    作为博弈论的重要算法:

    SG函数

    Sprague-Grundy

    一定要重点学习一下下(搞到我市选的时候崩了一题,泪奔~~~)
    学习SG函数之前,先要知道Nim游戏
    Nim游戏:两人对战,轮流操作,每次操作与人无关(就是A能做的,B也能做),当某方无法操作时,则该方败。
    经典的Nim游戏有捡石子游戏:给出N堆石子,每次选择一堆石子,取走任意个,不可不取,不能继续操作的输。
    经典的非Nim游戏有象棋:双方都不可以动对方的棋。

    Nim游戏主要问题是:先手是否有必胜策略。
    解决这个问题先定义游戏中的两种局面:P-positionN-position
    P-position:上一次移动的人有必胜策略
    N-position:现在移动的人优必胜策略
    那么Nim游戏满足一下几个要求:
    1、所有的最终局面(terminal—position)都是P-position
    2、所有的N-position都可以移动到一个P-position
    3、所有的P-position都不能移动到一个P-position

    那么就可以判断一种局面是否是P-position

    关键是判断条件

    先给出判断条件吧:
    对于一个Nim游戏局面(( a_{1}, a_{2}, ... , a_{n} )),它是P-position当且仅当(a_{1}igoplus a_{2}igoplus a_{3}...a_{n} =0 (igoplus ext 是异或号))

    证明

    1、对于terminal—position,异或和肯定是0,即是P-position,满足。
    2、设该局面的异或和为K,K的最高位为D。那么有一个数在二进制下第D位肯定是1,姑且设其为(a_{x}),令(a_{x}' =a_{x}igoplus k),则 (a_{x}' < a_{x})
    $ecause a_{1}igoplus a_{2}...a_{x}...igoplus a_{n} =K ( ) herefore a_{1}igoplus a_{2}...a_{x}' ...igoplus a_{n} =0( )ecause a_{x}' < a_{x} ( ) herefore ext 该操作可行( 3、反证:设局面)a_{1}igoplus a_{2}...a_{x}...igoplus a_{n} =0 ( 下一步局面为)a_{1}igoplus a_{2}...a_{x}' ...igoplus a_{n} =0 ( 则两式相等,因为异或运算满足消去律,所以)a_{x}' =a_{x}$
    该操作不可行。
    证毕。

    所以直接把初始局面的异或和求出来就可以判断是否有必胜策略。

    重点来了

    每一堆可以取的数目不一样怎么办???

    SG函数来拯救你!!!

    题目描述:有n堆石子,第i堆石子每次只能拿([1,i]),问先手是否有必胜策略。
    因为每堆石子可以取的个数不一样,所以难以判断一个操作是否可行,也就说不能用上面的证明。
    但可以利用SG函数来转化成普通的Nim游戏
    先定义一个操作mex(minimal excludant)为集合运算,表示最小的不属于该集合的最小非负整数。例如(mex) { (0, 1, 5) } $ = 2(,)mex$ { (1, 2, 5) } (= 0)
    (SG[x]=mex) { (SG[y] | ext y是x的后继) }
    1、对于terminal-position,因为没有后继,所以(SG=0)
    2、对于一个(SG eq 0)的点,一定有一个后继的(SG=0)
    3、对于一个(SG = 0)的点,一定没有一个后继的(SG=0)
    4、一个点均可到达([1,SG-1])的后继

    咦~,怎么这么熟悉的

    SG函数满足普通Nim游戏

    所以只要把原来每一堆的个数变成SG函数所对应的值就可以了!!!

    现在问题来了,SG函数怎么得到

    我也只能说:打表找规律吧。
    不过上述题目应该很容易就可以求出SG函数了。第i堆石子只能拿([1,i])个石子,先举个例子吧:i=2
    先把1~2i的SG求出来:SG[1]=1,SG[2]=2,SG[3]=0,SG[4]=1
    好像(SG[x]=x\%(i+1)).
    数学归纳法证明:
    ([0,i])必然满足(SG[x]=x\%(i+1)).
    归纳假设:对于(x>i),所有(y < x)都满足(SG[y] = y \% (i+1)).
    (x = k(i + 1) + b,0 leq b < i+1 , k > 0)
    则对于任意x能到达的数(y = (k - 1)(i + 1) + b + c,0 < c leq i)
    (SG[y] = (b + c) \% (i + 1))取完(0)(i)所有非(b)的数
    所以(SG[x] = b).
    证毕。

    所以说,规律自个找,证明没烦恼。

  • 相关阅读:
    父子组件的数据传递
    前端处理:elementUI 表格索引代表第几条数据
    qt的moc,uic,rcc命令的使用
    支持无限精度无限大数的类BigNumber实现
    二进制的妙用
    C#实现任意大数的计算和简单逻辑命题的证明——前言
    打磨程序员的专属利器——文本
    打磨程序员的专属利器——快捷键
    打磨程序员的专属利器——命令行&界面
    Linux命令全集
  • 原文地址:https://www.cnblogs.com/GerynOhenz/p/4382237.html
Copyright © 2011-2022 走看看