算法介绍:

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. 产生冠军 HDU - 2094 (拓扑排序)

    分析: 当有且只有一个节点入度为0时,该节点即为冠军,否则不能产生冠军.所以以下代码中只要入度大于0的无论是几都将其设置为1. #include <stdio.h> #include &l ...

  2. Android——<uses-sdk>

    语法(SYNTAX): <uses-sdk android:minSdkVersion="integer" android:targetSdkVersion="in ...

  3. pillow模块

    pillow模块 用于操作图片的模块 安装 pip install pillow 生成验证码 from PIL import Image,ImageDraw,ImageFont from io imp ...

  4. Mac上homebrew使用

    一.官方网址 Homebrew 二.目录 安装 查看帮助信息 查看版本 更新Homebrew自己 安装软件包 查询可更新的包 更新包 (formula) 清理旧版本 锁定不想更新的包 卸载安装包 查看 ...

  5. docker.[6] 数据卷

    docker.[6] 数据卷 操作指令: # docker run -v /data1:/data2 -i -t centos /bin/bash 参数说明: data1 : 这里指的是宿主机的目录( ...

  6. java 3 接口与多态&输入输出流

    接口 中的所有方法都是方法 抽象 使用接口实现多继承 类型的装换 数据成员就变成了static 和 final food 和 snow 都是可以吃的 可以同时实现多个接口 接口与接口之间也可以有继承关 ...

  7. Linux 上GCC的静态编译和动态编译

    静态编译 常规编译示例: $gcc xxx.c yyy.c zzz.c -o rslt 注明: gcc编译器会对源文件min.c进行预处理, 编译, 以及链接, 最后生成可执行文件 $gcc -c x ...

  8. LintCode刷题笔记--Flip Bits

    Flip Bits: 标签:位运算 题目:Determine the number of bits required to flip if you want to convert integer n  ...

  9. bzoj2073 PRZ

    Description 一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍在桥上的人都不能超过一定的限制. 所以这只队伍 ...

  10. cmd 命令重启远程服务器

    今天,连接服务器突然无法连接远程桌面,更无法重新启动机器,先进行了ping  操作: 机器运行正常... 后通过远程软件发现,可以用命令...这是一个新发现  …^ .^ 1.输入cmd  运行正常. ...