• [转载]NIM(1) 一排石头的游戏


    http://dev.firnow.com/course/3_program/c++/cppjs/20090524/167795.html

    若规定最后取光石头的人输,又该如何应对呢(还有必胜的策略么?)?

    仍然用<1,1,1,1>这种形式来表示石头.仍然是你先取.

    如果是1块,你必输.

    如果是2块,你赢.你可以在边角取走一块,然后便成为:这时候只剩1块石头,对手先取.这样就成1块石头的情况,结果当然是对手输

    如果是3块,你赢.你可以在边角取走两块,然后便成为:这时候只剩1块石头,对手先取.......

    如果是4块,你必输.石头是<1,1,1,1>.如果你从边角取走一块或相邻两块,那么局势便成为:这时候只剩3块 (<1,1,1>)或2块(<1,1>),而对手先取,由2块或3块的结论便知道对手肯定赢.如果你从中间取1块,那么成 为<1,1,0,1>,对手只要取走2块,你就输,如果你取走中间两块,那么便成为<1,0,0,1>对手只要取走1块,你便 输.

    如果是5块呢?你必赢.因为你可以从边角取走一块,然后局势便成为只剩下4块<1,1,1,1>,而这时候是对手取,从4块结论便可以知道对手会输.

    从第5块已经可以有点推论了.

    对于N块石头,N足够大.便有以下结论:

    如果N块石头你必输的话,那么N+1,N+2你必赢.因为你可以取走边角的1块或2块,然后就剩下了N块石头,并且是对手取,对手必然会输.

    那么对N+3呢?不知道.

    仍然是N块的时候输.对N-1,跟N-2,结果是必然赢,可以用反证法,假设N-1是输的.那么(N-1)+1必然赢,也就是N块是赢的,矛盾了.所以N-1必赢,N-2也类似.

    ##############################################################

    可以得出的结论:

    如果N是必输,那么:

    你:N-1 赢      对手:N-1必输,(这里对手能保证使自己输,证明可以跟上面类似的证明.下同)

       N-2 赢           N-2必输

       N   必输         N必赢

       N+1赢            N+1必输

       N+2赢            N+2必输

    于是:

    1输 2赢 3赢 4输....可以得出的是:1+3k为输, 2+3k跟3+3k为赢.

    输表示对手可以控制,使你拿走走后的块,赢就表示你可以控制,使对手拿走最后的块,除非你放水.

    ################################################################

    难的是如何实际操作:

    设N = 3K + 1,(也就是前面证出的你必输的情况).对手该如何操作来赢.

    如果你从边角取走1块或2块,留给对手的便是N-1,N-2并且是连续的,对手就取2块或1块,使石头剩余N-3并且连续,这时候N - 3 = 3(K -1) + 1,你仍然是输的局势.也就是说,如果你从边角取,对手赢是必然的.所以你想赢(虽然结果是输),剩余的路就只有从中间取(不一定是中心).

    那只有两种分支了:

    !!!第一种,你从中间(不一定是最中心)取1块.

    写出石头阵<.....1......>,只列出了其中的你要取的那1块.设左边部分为A(左边的省略号),右边部分哦为B. A跟B的数目会有以下几种形式:

    (1)A = 3P,     B = 3Q

    (2)A = 3P + 1, B = 3Q - 1 = 3(Q-1) + 2

    (3)A = 3P + 2, B = 3Q - 2 = 3(Q-1) + 1

    (1)这种形式,对手只要在你取的那一块的左边或右边取走2块,就赢.假设取走A中的2块,因为剩下的局势是

    A = 3P - 2 = 3(P -1) + 1, B = 3Q,这时候是你取,如果从A那部分下手,对手是可以保证让你最后取完,在你取完A中的部分后,接下来便是对手取,局势就是,剩余3Q块,对手先取,由前 面的结论,对手必然赢.如果你从B那部分下手,由前面的结论,对手是可以保证最后取完的是对手,然后就是你先取剩下的A那部分,由前面的结论,你仍然输.

    剩下的(2),(3)中类似.

    有人说我可以从A取一点,等对手取,对手取后再从B取一点啊?这样想:有两块饼干A,B,两个人吃,每人每次只能掰1/4块饼干吃,谁吃到最后的1 /4块就算赢,规定你先吃.你从A吃一点,然后又从B吃一点,这样能改变结果么?其实,这改变的知识吃的步骤,可能本来第2步的动作你放到第3步去 做...对结果并无影响.取石头也一样.

    !!!第二种,你从中间(不一定是最中心)取2块.这种其实跟第一种(取1块)一样.不同的是第一种对手要取2块,而第二种对手只取1块就可以.

    还有个问题,就是你拿完1块后,剩下A跟B部分,你是怎么确定拿完的顺序的?其实很简单,你可以从比较小的数字N开始证明(比如N=7,这时候A跟 B都是很小的).其实这个证明是个归纳证明.你已经知道1块石头输,2块赢,3块赢,4块输,那么你就能推出7(因为推7块用到的都是1,2,3,4块的 情况),然后继续往下推,不就可以推到无限的么?

    又有个问题,当剩余A跟B部分后,我可以先拿A或B中中间的石头啊,比如拿A的中间的石头,这样不就剩余3部分了么?你把A当作整体看,问题就解决了.实在想不通,其实就是又将上面的证明一遍.

    具体的步骤就是:

    N = 3K + 1.对手赢:如果你从边上拿,对手就从你拿的位置的邻近的地方拿走相应的块数,保持剩余的石头的个数为3P + 1个,对手就赢.如果你从中间拿,对手就从你拿的位置的左右拿相应的块数,使总数保持3P + 1,并且剩余两部分,一部分为3的倍数个(另一部分当然就是3的倍数加1个).

    对于N = 3K + 2,你赢.你从边上拿走1块石头,就转化为:留下N = 3K + 1,让对手拿,对手也就必输了.

    对于N = 3K + 3,你赢.你从边上拿走2块石头,.....

    分析很透彻,从中间拿石头相当于把原问题分为两个独立的子问题。

  • 相关阅读:
    listener中@Autowired无法注入bean的一种解决方法
    PBKDF2加密的实现
    springmvc集成shiro后,session、request是否发生变化
    java加密解密工具类
    springMVC中controller层方法中使用private和public问题
    密码强度正则表达式 – 必须包含大写字母,小写字母和数字,至少8个字符等
    Java判断两个时间相差的天数
    Java中Date、String、Calendar类型之间的转化
    JavaScript前端和Java后端的AES加密和解密(转)
    JS前端加密JAVA后端解密详解
  • 原文地址:https://www.cnblogs.com/bigrabbit/p/2555357.html
Copyright © 2020-2023  润新知