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

    由于笔者太懒,懒得把原来的markdown改成MCE,所以有很多奇怪的地方请谅解。

    先说nim游戏。

    大意:有n堆石子,两个人轮流取,每个人每次从任意一堆取任意个,直到一个人无法取了为止。问对于石子的情况先手的输赢。

    这看上去无从入手,但是仔细想想还是有法的。

    我们从最终态逆推,首先考虑(0,0,0)的情况,一看就gg了,无论谁面对这种情况都只能愿赌服输。
    那么我们考虑如果我们是后手,应该怎么样才可以赢。于是我们考虑,如果出现这么一种情况(0,n,n),我们是不是处于必胜的状态。考虑当下情况,无论对方从任何一堆里取多少个,那么我们总可以从另一堆里取到相同个数然后保持当前局势。这样对方取完任何一堆,我们都可以相应的取完另一堆然后把(0,0,0)的gg局势扔给对方。

    那么我们怎样才能使当前局势成为(0,n,n)呢?
    我们首先从简单的例子开始:
    对于情况(1,2,3),我们将这三个数二进制掉。
    则:

    1:01
    2:10
    3:11
    所以1^2^3==0。
    然后我们可以得出,对于任意一个f[1]^f[2]^……^f[n]==0,我们总能神乎其技的把当前情况简化成(0,n,n)来使自己必胜,反之我们就必败了。

    所以我们就得出了nim游戏的一般结论。

    ## 然后说说sg值

    先说说必败点和必胜点吧。

    必败点:无论哪一方取时处于这个位置,那么必败无疑。

    必胜点:无论哪一方取时处于这个位置,那么不用往后算,他已经赢了。

    我们把必败点和必胜点用P和N表示。

    ### 给出几条性质:

    1.对于任何一个必败点, 它仅能转移到必胜点。

    2.对于任何一个必胜点,它都有至少一种方法转移到必败点。

    3.必败点为游戏的终结点(推理基础,建立在没有平局的基础上)。

    (我们以先手为第一人称)

    解释一下这几个性质。

    对于性质1,我们如果想要失败的话,在我们当前的位置,我们只能转移到一个必胜的位置来让对方继续。

    对于性质2,我们如果要胜利,在我们当前位置,一定可以转移到一个必败点来让对方失败。

    对于性质3,无论谁取到必败点,都会陷入以上两个性质的恶性循环而失去所有胜利的机会。

    那么我们看一个例子:

    给定一堆n个石子,两个人轮流从里面取2的幂次方个,求先手的策略。

    对题目进行分析,我们可以取得个数有1,2,4,8,16,32……

    那么由最终态分析:

    当n=0时,为一个必败点P,因为很明显你不能操作了。

    n=1时,为必胜点。

    n=2时,为必胜点。

    n=3时,无论怎么取,要么剩1个要么剩两个,根据性质1,我们gg了。

    以此类推

    n=0~7
    胜负为:PNNPNNPN

    规律还是比较明显的。

    ## 然后我们引入sg值

    笔者太懒,百科复制定义了,其实也没大用:
    ```
    游戏和的SG函数等于各个游戏SG函数的Nim和。
    这样就可以将每一个子游戏分而治之,从而简化了问题。
    而Bouton定理就是Sprague-Grundy定理在Nim游戏中的直接应用,因为单堆的Nim游戏SG函数满足 SG(x) = x。
    ```
    首先我们要知道这样的一个定义:mex({?})就是集合中没出现的最小的非负整数。例如mex(1,2,3)=0,mex(0,1,2,4……)=3。

    对于任意状态 x , 定义 SG(x) = mex(S),其中 S 是 x 后继状态的SG函数值的集合。如 x 有三个后继状态分别为 SG(a),SG(b),SG(c),那么SG(x) = mex{SG(a),SG(b),SG(c)}。 这样 集合S 的终态必然是空集,所以SG函数的终态为 SG(x) = 0,当且仅当 x 为必败点P时。

    可能不好理解,还是给个例子:

    假设我们有一堆n个石子,我们只能从里面取1,2,5这些。
    ```
    那么首先:
    SG[0]=0,因为总是这样的。
    SG[1]=mex(0)=1
    SG[2]=mex(0,1)=2
    SG[3]=mex(1,2)=0
    SG[4]=mex(2,3)=0
    SG[5]=mex(0,3,4)=1
    以此类推……
    ```
    由此我们可以得出SG值的求法,一个状态数组f,一个后继状态集合S,加上SG即可求出。

    可以做一下[Fabonacci again and again](http://acm.hdu.edu.cn/showproblem.php?pid=1848)来熟悉一下代码。

  • 相关阅读:
    kettle imestamp : Unable to get timestamp from resultset at index 22
    ImportError: No module named setuptools 解决方案
    Tesseract-OCR
    python截图
    connect to SQL Server in python on centos
    vertica merge 优化
    kettle crontab java: command not found
    Idea 使用maven+tomcat的时候,编译指定的Profile
    Java中Vector和ArrayList的区别
    Docker入门命令
  • 原文地址:https://www.cnblogs.com/victorique/p/8460129.html
Copyright © 2011-2022 走看看