zoukankan      html  css  js  c++  java
  • Nim证明即推导

    (Nim)游戏:
    (N)堆石子,每堆(a[i])个石子,(Alice)(Bob)轮流行动,(Alice)先行动,操作规则如下
    1、两方轮流操作
    2、每次可取走任意一堆的任意数量石子,不能取成负数
    3、无法行动的一方为输

    定义先手必胜局面,N局面,表示当前局面为先手必胜(即面对该局面的玩家一定有获胜的策略)
    定义先手必败局面,P局面,表示当前局面为先手必败(即面对该局面的玩家一定没有机会获胜)
    易得到
    ({color{Red} {1、所有终止局面一定为P局面}})
    ({color{Red} {2、可以到达P局面的局面为N面}})
    ({color{Red} {3、所有操作都将导致N局面的局面为P局面}})
    所以,博弈论的胜负决策可以按一下步骤确定
    1、标记所有终止状态为P状态
    2、寻找所有能到达P状态的点,标记为N状态
    3、寻找所有子状态都为N状态的点,标为P状态。如果没有,则退出
    但是,显然按上面这种算法会狂T不止,且码量巨大,所以,我们引进一个新函数
    定义(mex(x))(x)为自变量,表示一个集合,(mex(x))定义为集合中未出现过的最小自然数
    定义(sg(x)),令(y)(x)的子状态集合,(z)为的某一元素(y),则(sg(x)=mex(sg(z)))
    又可以得到
    ({color{Red} {sg(所有终止局面)=0(没有子状态)}})
    ({color{Red} {sg(可达终止局面的状态) e0}})
    ({color{Red} {sg(子状态的sg值均不为0的状态)=0}})
    上面三个式子都很显然
    然后,我们就发现了一个类似的规则
    (sg=0)时其状态为P状态
    (sg e0)时其状态为N状态(对比红字)

    如何判断多堆石子时的胜负情况?
    首先,很显然,
    当局面为 (egin{matrix}2n\overbrace{ k+k+cdots+k }end{matrix}) 时,先手必输
    (N)堆石子,每堆数量为(a_{i})
    将每个(a_{i})转化为二进值,并将前导零补全
    (a_{i}=a_{j}=k(1leq i<jleq n))
    所有(a_{i})转化为二进值都是相同的
    例如,(k=22)
    (10110)
    (10110)
    每次先手的操作,都可以看做在其中一个(k)中,将一些0变为1,1变为0
    例如把k取成17
    (10{color{Red} {001}})
    (10110)
    此时对手也可以采取相同操作,将下面的也取成17
    (10{color{Red} {001}})
    (10{color{Red} {001}})
    上面一点大家都懂,只是一个引入

    当存在(a_{i} e a_{j})时,如何操作?
    拿3、5、6为例
    (011)
    (101)
    (110)
    观察发现,每一纵列都有偶数个1,这意味着
    当一方取走任意一个1时,另一方都有相同的策略取走另一个1,使其保持纵列仍然为偶数个1
    当一方将任意一个0改变为1时,另一方都有相同的策略取走一个1(注意,不是补0),使其保持纵列仍然为偶数个1
    这跟上面讲到过的策略一样,正确性显然
    所以,我们得出这么一个结论,当每一列的1的个数均为偶数时,先手必败,反之先手必胜
    再简化一点,当(a_{1}otimes a_{2}otimes a_{3}otimescdotsotimes a_{n}=0)时((otimes)表示异或),先手必败,反之先手必胜
    再推广,可得一个平等组合游戏中,该游戏的(sg)值等于其所有子游戏的(sg)值的异或和

    胜负判断知道了,如何得到必胜策略(如果存在的话)
    (a_{1}otimes a_{2}otimes a_{3}otimescdotsotimes a_{n}=k(k e0))
    因为

    [a_{1}otimes a_{2}otimes a_{3}otimescdotsotimes a_{n}=k(k e0) ]

    很显然

    [a_{1}otimes a_{2}otimes a_{3}otimescdotsotimes a_{n}otimes k=kotimes k=0 ]

    [kleq max(a_{1},a_{2},a_{3},cdots,a_{n}) ]

    设k的二进值最高位为第x位,则在(a_{1}sim a_{n})中,至少存在一个(a_{i}),二进值第x位也为1
    所以

    [a_{i}otimes k<a_{i} ]

    [a_{1}otimes a_{2}otimes a_{3}otimescdotsotimes a_{i}otimes kotimescdotsotimes a_{n}=0(k e0) ]

    因为(a_{i}otimes k<a_{i}),所以存在(a_{i}),将其取成(a_{i}otimes k)即可

  • 相关阅读:
    Apache Pig使用MongoLoader产生大量空文件问题
    执行sparksql出现OOM问题
    [TD笔记]Teradata XML
    Redhat上离线/非root安装python库
    Java 多线程同步关键字synchronized各种用法/特性 总结
    CVE-2019-0708 微软远程桌面服务远程代码执行漏洞分析之补丁分析
    Spring Security 实战(使用Spring Boot项目演示)
    一些渗透中,或者扫描的nmap nse脚本推荐
    kali学习笔记(一):虚拟机安装好kali后应进行的配置
    Spring boot相关问题
  • 原文地址:https://www.cnblogs.com/hzf29721/p/10217006.html
Copyright © 2011-2022 走看看