算法介绍:

Nim游戏是指两个对手在m个堆中轮流随意从某一个堆中拿出n个元素,假定两个对手都是足够聪明,直至最后一次取的人将所有元素取出,此人取得胜利。与之相反的是Misere游戏,相同的游戏规则,但是最后一次取的人将落败。

为了解决这个问题,有一个叫做nim-sum的方法加以解决,这个方法是这样的

设有三个堆分别是 Heap A, Heap B,Heap C,每个堆分别有8,12,13个元素

1)将每个堆的元素使用二进制表示,分别是1000,1100,1101

2)对三个数进行异或操作,即:

1000
1100
1101
-------
1001

就是十进制的9,这个就是三个堆的nim-sum,如果nim-sum为0,则先手者不可能胜出

3)使用这个计算出来的nim-sum再次分别于三个堆中元素个数进行异或操作,如果得到异或的结果小于堆数则为可选的必胜的操作,即:

情况一:

1000
1001
-------
0001<1000,可以为必胜操作,此时先手者可以从Heap A中取出8(1000)-1(0001)=7个元素,则下一步的nim-sum为0,接下来的策略就是依照这个算法继续进行,模拟操作如下:

HeapA  HeapB  HeapC Nim-Sum

8              12           13             9           先手者从Heap A中拿出7个元素,使得下一步的nim-sum为0,则先手者胜出

1              12            13            0           后手者从Heap B中拿出5个元素

1               7             13            11          先手者从Heap C中取出13-(13^11)=7个元素

1               7               6              0         后手者从Heap B中取出5个元素

1               2               6              5         先手者从Heap C中取出6-(6^5)=3个元素

1               2               3             0          后手者从Heap C中取出3个元素

1               2               0             3          到这一步,如果是nim游戏,则在HeapB中取出1个元素(如果是misere游戏,则全取HeapB所有元素)

1               1               0             0          后手者取出HeapA中一个元素

0               1               0              1         先手者取出HeapB中最后一个元素,先手者胜出

情况二:

1100
1001
-------
0101<1100,可以为必胜操作,此时先手者可以从Heap B中取出12(1100)-5(0101)=7个元素

情况三:

1101
1001
-------
0100<1101,可以为必胜操作,此时先手者可以从Heap C中取出13(1101)-4(010)=9个元素

分析:

如上面8 12 13

对情况一,三个堆可分解为

HeapA    1    7

HeapB   12

HeapC   12   1

多出元素为HeapA中的7,取出后三个堆呈现对称分布

对情况二,三个堆可分解为

HeapA     8

HeapB     5      7

HeapC     5      8

多出元素为HeapB中的7,取出后三个堆呈现对称分布

对情况三,三个堆可分解为

HeapA    8

HeapB    8     4

HeapC    4     9

多出元素为HeapC中的9,取出后三个堆呈现对称分布

总结:

1.可以通过计算所有堆的nim-sum得出先手者是否可以取胜,如果不是0则可以,为0则不可以

2.可以用计算后的nim-sum分别与所有堆的元素进行异或操作,如果得到结果小于原来堆的元素,则为可选操作

以上分析来自:http://blog.csdn.net/lawrencesgj/article/details/7828935

HDU 1850 Nim-Sum思想总结、的更多相关文章

  1. HDU 1850 (Nim博弈 取胜方案数) Being a Good Boy in Spring Festival

    考虑到Bouton定理的证明过程,设n个数的Nim和(异或和)为X,其最高位的1在第k位,那么n个数中一定有个y的第k为也是个1. 将y的数量变为X xor y,那么n的数的Nim和为0,便转为先手必 ...

  2. poj 3975&amp;&amp;hdu 1850 (nim)

    //赢得了上风 //从n几年移除堆叠一堆石头,有多少可取的石头堆 # include <stdio.h> # include <string.h> # include < ...

  3. HDU - 1850 Nim博弈

    思路:可以对任意一堆牌进行操作,根据Nim博弈定理--所有堆的数量异或值为0就是P态,否则为N态,那么直接对某堆牌操作能让所有牌异或值为0即可,首先求得所有牌堆的异或值,然后枚举每一堆,用已经得到的异 ...

  4. hdu 1850 Being a Good Boy in Spring Festival(Nimm Game)

    题意:Nimm Game 思路:Nimm Game #include<iostream> #include<stdio.h> using namespace std; int ...

  5. HDU.1850 being a good boy in spring festival (博弈论 尼姆博弈)

    HDU.1850 Being a Good Boy in Spring Festival (博弈论 尼姆博弈) 题意分析 简单的nim 博弈 博弈论快速入门 代码总览 #include <bit ...

  6. HDU 1024 Max Sum Plus Plus --- dp+滚动数组

    HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...

  7. HDU 1003 Max Sum --- 经典DP

    HDU 1003    相关链接   HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...

  8. HDU 1244 Max Sum Plus Plus Plus

    虽然这道题看起来和 HDU 1024  Max Sum Plus Plus 看起来很像,可是感觉这道题比1024要简单一些 前面WA了几次,因为我开始把dp[22][maxn]写成dp[maxn][2 ...

  9. hdu 3415 Max Sum of Max-K-sub-sequence(单调队列)

    题目链接:hdu 3415 Max Sum of Max-K-sub-sequence 题意: 给你一串形成环的数,让你找一段长度不大于k的子段使得和最大. 题解: 我们先把头和尾拼起来,令前i个数的 ...

  10. HDU 1024 Max Sum Plus Plus (动态规划)

    HDU 1024 Max Sum Plus Plus (动态规划) Description Now I think you have got an AC in Ignatius.L's "M ...

随机推荐

  1. git解决冲突的最佳方法

    用eclipse egit 去pull 代码出现冲突 点击details  全选复制到记事本上 如上图选择3个冲突中的一个   eclipse快捷键  ctrl + shift+R  张贴   回车 ...

  2. PHP闭包实现函数的自调用实现递归

    根据pathinfo访问对应得controller,如ip:port/home/index/index则会访问home目录下的IndexController的index方法:如果不指定pathinfo ...

  3. scala/java读取项目中的文件

    一.获取jar包的位置 1.使用类路径 String path = this.getClass().getProtectionDomain().getCodeSource().getLocation( ...

  4. 【JZOJ4747】【NOIP2016提高A组模拟9.3】被粉碎的线段树

    题目描述 输入 第一行包括两个正整数,N ,M ,分别表示线段树的宽以及询问次数. 以下N-1 行以先序遍历(dfs深搜顺序)描述一个小R线段树,每行一个正整数表示当前非叶子节点的 mid,保证每个节 ...

  5. [React Native]去掉WebStorm中黄色警告

    用WebStorm开发RN难免会碰到一大堆黄色警告.就像下面这样. 其实这个错误并不会影响开发,但是作为一个上升处女座的,我很难忍.于是各种想办法. 上网查了半天发现这篇文章 http://blog. ...

  6. 2019.9.10附加题while练习

    题目:企业发放的奖金根据利润提成.利润(I)低于或等于10万元时,奖金可提10%:利润高于10万元,低于20万元时,低于10万元的部分按10%提成,高于10万元的部分,可提成7.5%:20万到40万之 ...

  7. OpenJudge_1936:All in All

    描述 You have devised a new encryption technique which encodes a message by inserting between its char ...

  8. C++复制初始化的限制

    相比于直接初始化,复制初始化有更加严格的限制. 1:在复制初始化时,不能使用声明为explicit的构造函数进行的隐式转换.而直接初始化则是允许的: struct Exp { explicit Exp ...

  9. 阿里云数据库自研产品亮相国际顶级会议ICDE 推动云原生数据库成为行业标准

    4月9日,澳门当地时间下午4:00-5:30,阿里云在ICDE 2019举办了主题为“云时代的数据库”的专场分享研讨会. 本次专场研讨会由阿里巴巴集团副总裁.高级研究员,阿里云智能数据库产品事业部负责 ...

  10. 【Linux】 经典Linux系统工程师面试题(转载)

    1.如何将本地80端口的请求转发到8080端口,当前主机IP为192.168.16.1,其中本地网卡eth0: 答: # iptables -t nat -A PREROUTING -d 192.16 ...