HDU 1850 Nim-Sum思想总结、
算法介绍:
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思想总结、的更多相关文章
- 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,便转为先手必 ...
- poj 3975&&hdu 1850 (nim)
//赢得了上风 //从n几年移除堆叠一堆石头,有多少可取的石头堆 # include <stdio.h> # include <string.h> # include < ...
- HDU - 1850 Nim博弈
思路:可以对任意一堆牌进行操作,根据Nim博弈定理--所有堆的数量异或值为0就是P态,否则为N态,那么直接对某堆牌操作能让所有牌异或值为0即可,首先求得所有牌堆的异或值,然后枚举每一堆,用已经得到的异 ...
- hdu 1850 Being a Good Boy in Spring Festival(Nimm Game)
题意:Nimm Game 思路:Nimm Game #include<iostream> #include<stdio.h> using namespace std; int ...
- HDU.1850 being a good boy in spring festival (博弈论 尼姆博弈)
HDU.1850 Being a Good Boy in Spring Festival (博弈论 尼姆博弈) 题意分析 简单的nim 博弈 博弈论快速入门 代码总览 #include <bit ...
- HDU 1024 Max Sum Plus Plus --- dp+滚动数组
HDU 1024 题目大意:给定m和n以及n个数,求n个数的m个连续子系列的最大值,要求子序列不想交. 解题思路:<1>动态规划,定义状态dp[i][j]表示序列前j个数的i段子序列的值, ...
- HDU 1003 Max Sum --- 经典DP
HDU 1003 相关链接 HDU 1231题解 题目大意:给定序列个数n及n个数,求该序列的最大连续子序列的和,要求输出最大连续子序列的和以及子序列的首位位置 解题思路:经典DP,可以定义 ...
- HDU 1244 Max Sum Plus Plus Plus
虽然这道题看起来和 HDU 1024 Max Sum Plus Plus 看起来很像,可是感觉这道题比1024要简单一些 前面WA了几次,因为我开始把dp[22][maxn]写成dp[maxn][2 ...
- hdu 3415 Max Sum of Max-K-sub-sequence(单调队列)
题目链接:hdu 3415 Max Sum of Max-K-sub-sequence 题意: 给你一串形成环的数,让你找一段长度不大于k的子段使得和最大. 题解: 我们先把头和尾拼起来,令前i个数的 ...
- 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 ...
随机推荐
- mac pro 1.5T内存是如何实现的
苹果发布全新Mac Pro:28核1.5T内存 预计售价10万+ 看到这样的新闻标题是不是很震撼,甚至怀疑人生,64位机怎么就可以1.5T内存了,自己的系统盘都没那么大 而且我们知道windows下的 ...
- Katalon系列二十一:用例中语句失败处理
假如有一个用例:1.登陆2.下单3.对历史单评价4.退出 情况一:当第1步执行失败时,我们希望用例不再执行,因为再执行也没有意义了,反而浪费时间:情况二:当第2步执行失败时,我们希望能略过第2步操作, ...
- UIImageView添加圆角
最直接的方法就是使用如下属性设置: 1 2 3 imgView.layer.cornerRadius = 10; // 这一行代码是很消耗性能的 imgView.clipsToBounds = YES ...
- 【水滴石穿】RNNewsGo
项目地址为:https://github.com/ImVeryGood/RNNewsGo 我们先来看一下页面 分析了一下项目,项目也是有用到redux-saga的 然后模块比较清晰 接下来我们分析代码 ...
- Directx教程(28) 简单的光照模型(7)
原文:Directx教程(28) 简单的光照模型(7) 现实生活中的点光源都是随着距离衰减的,比如一个电灯泡在近处会照的很亮,远处光线就很弱.本节中我们在前面光公式的基础上,再给漫反射和 ...
- 纯CSS3个性化圆形按钮登录表单
在线演示 本地下载
- zabbix监控docker容器
1.环境说明 由于最近zabbix进行过一次迁移,所以zabbix-server系列采用docker方式安装,参考zabbix官网:https://github.com/zabbix/zabbix-d ...
- windows和linux下读取文件乱码的终极解决办法!
乱码是个很恶心的问题. windows和linux读取txt文件,一旦读取了,编码发生改变,就无法再还原了,只有重启项目. 网上有很多方法都是读取文件头,方法很好,但是亲测都不能用(右移8位判断0xf ...
- POJ 2632 Crashing Robots (模拟 坐标调整)(fflush导致RE)
题目链接:http://poj.org/problem?id=2632 先话说昨天顺利1Y之后,直到今天下午才再出题 TAT,真是刷题计划深似海,从此AC是路人- - 本来2632是道略微恶心点的模拟 ...
- MySQL中使用LIMIT进行分页的方法
一.分页需求: 客户端通过传递start(页码),pageSize(每页显示的条数)两个参数去分页查询数据库表中的数据,那我们知道MySql数据库提供了分页的函数limit m,n,但是该函数的用法和 ...