转|poj2234maches game|博弈论

以下内容转自精灵的博客。
时间限制:
    1000ms
内存限制:
    65536kB

描述
    Here is a simple game. In this game, there are several piles of matches and two players. The two player play in turn. In each turn, one can choose a pile and take away arbitrary number of matches from the pile (Of course the number of matches, which is taken away, cannot be zero and cannot be larger than the number of matches in the chosen pile). If after a player’s turn, there is no match left, the player is the winner. Suppose that the two players are all very clear. Your job is to tell whether the player who plays first can win the game or not.
输入
    The input consists of several lines, and in each line there is a test case. At the beginning of a line, there is an integer M (1 <= M <=20), which is the number of piles. Then comes M positive integers, which are not larger than 10000000. These M integers represent the number of matches in each pile.
输出
    For each test case, output "Yes" in a single line, if the player who play first will win, otherwise output "No".
样例输入

2 45 45

3 3 6 9

样例输出

No

Yes

(一)这是一道博弈论Nim Game的题目,我们先从简单情况开始分析,再逐步深入。

(1)只有一堆,先手赢
(2)两堆,一共2根火柴,后手赢              (取完一堆即可)
  两堆,一共3根火柴,先手赢               (1+2格局,在2个的一堆中取1个,转化为前一种情形)
  两堆,一堆2个,另一堆2个,后手赢 (取完一堆,或者取1个都必输)
  两堆,一堆1个,另一堆3个,先手赢 (1+3格局,在3个的一堆中取2个,转化为2根的情形)
          ...   
  两堆,堆中火柴数目相等,后手赢
  两堆,堆中火柴数目不等,先手赢  
(3)三堆,一共3根火柴,先手赢
  三堆,一共4根火柴,先手赢
  三堆,一共5根火柴,1.1.3型先手赢   (因为总能够转化到两堆相等的情况)
  三堆,一共5根火柴,2.2.1型先手赢   (因为总能够转化到两堆相等的情况)
  三堆,一共6根火柴,2.2.2型先手赢
  三堆,一共6根火柴,1.1.4型先手赢
  三堆,一共6根火柴,1.2.3型后手赢

通过简单的分析发现规律并不易寻找,并不是简单的奇偶关系(我就错误地推出过奇偶胜负关系)

(二)我们开始深入一点

我们发现在两堆时,我们找到一个有趣的规律,那就是如果两堆数目相等,那么后手方赢,如果两堆数目不等,先手方赢(思考一下为什么?)。但三堆的时候貌似又行不通了,因为如最简单的1+1+1格局,显然是各堆数目相等,但应该是先手方赢。但我们马上会发现,对于三堆的情形,如果各堆数目相等,一定是先手方赢(想清楚为什么?)。进一步推广,我们可以得到如下结论:

堆为奇数个,各堆中火柴数目相等,一定是先手方赢

堆为偶数个,各堆中火柴数目相等,一定是后手方赢

(三)我们开始处理最棘手的部分

我们现在能够处理,所有堆中火柴都相等的时候的情形,但各堆中火柴不相等呢?这里我们再次看到数学中一些不可思议的联系。我们现在重新审视和定义这个游戏的胜负

(1)如果轮到某人取火柴的时候,火柴已经没有了,那么此人输,设为P-格局

(2)如果轮到某人取火柴的时候,他能够取完火柴,那么此人赢,设为N-格局

(3)如果轮到某人取火柴的时候,他能够将当前格局转化为某个P格局,那么此格局为N-格局

(4)如果轮到某人取火柴的时候,他不能将当前格局转化为某个P格局,那么此格局为P-格局

下面我们来推导一个定理:一个格局记为(x1,x2,...,xn),且次序无关,此格局为 P-格局 当且仅当 x1^x2^...^xn = 0.其中^是按位异或运算

推导:  对应上述4种情形(为了叙述的简洁,并不十分严谨地证明,而是直接假设结论正确,再说明定理的工作机制)

(1)当(x1,x2,...,xn)中全为0时            ,格局为P-格局,此时x1 ^ x2 ^ ... ^ xn = 0成立。

(2)当(x1,x2,...,xn)中只有一个不为0,格局为N-格局,此时x1 ^ x2 ^ ... ^ xn = 0不成立。

(3)当(x1,x2,...,xn)是P-格局时,x1,...,xn不全为0.(反证法)

假设x1 ^ x2 ^ ... ^ xn = p,且p不为0,

记 p 的二进制表示中,最左的1(最高位的1)在从左至右数第 k 位.

由于p是异或运算的结果,那么 x1, x2 , ... , xn中至少有一个数第k位为1,

不妨设 xi 的第 k 位为1,那么 xi ^ p 第 k 位为0,那么xi > xi^p 显然成立.

也就是说,存在某种取法,使i堆的火柴数变化到 xi^p .

题设x1 ^ x2 ^ ... ^ xn = p,那么x1 ^ x2 ^ ... ^ xn ^ p = 0.

那么当前格局可以转化到某个P-格局,也就是说当前格局时N-格局,矛盾

所以,必有p=0.

(4)当x1 ^ x2 ^ ... ^ xn = 0时,如果存在某个移动 xi 变化到 xi ’ ,且x1^x2^....^xi ‘ ^...^xn = 0,

那么由异或运算的消去律有,xi = xi ‘ ,也就是说一根火柴都没取,这不允许的,所以

当前格局只能是P格局

有了这个强大的定理那么上题就很好解决了:

    #include <iostream>
    using namespace std;  

    int main()
    {  

        int M;
        while(cin>>M)
        {
            /*input*/
            int pile[20] ={};
            for(int i=0; i<M; ++i)
            {   cin>>pile[i]; }  

            /*calculate*/
            int result   = 0;
            for(int i=0; i<M; ++i)
            {   result ^= pile[i];  }  

            /*output*/
            if(result)cout<<"Yes"<<endl;
            else      cout<<"No" <<endl;
        }  

        return 0;
    }  
时间: 2025-01-04 21:04:18

转|poj2234maches game|博弈论的相关文章

hdu 1536 S-Nim 博弈论,,求出SG&#39;函数就可以解决

S-Nim Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4975    Accepted Submission(s): 2141 Problem Description Arthur and his sister Caroll have been playing a game called Nim for some time now

UVA 10561 Treblecross(博弈论)

题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=32209 [思路] 博弈论. 根据X分布划分禁区,每个可以放置的块为单独一个游戏.按长度定义状态,构造sg函数.依次试验每一种放法. [代码] 1 #include<cstdio> 2 #include<vector> 3 #include<cstring> 4 #include<algorithm> 5 using names

博弈论的学习之始

今天看了耶鲁大学关于<博弈论>的公开课视频.于是想记录下关于博弈论的学习经历.最近赶上期末,事情超多,唉!不定期观看并记录吧! 视频中没有给出博弈论的具体定义,就不记录了吧!英文名Game Theory. 教授推荐课程书籍:杜塔 <策略与博弈>(课程基础书籍).乔治·沃森<策略>(教授说偏难!).<战略思想>(没看到具体谁的,教授说用来催眠不错!) 第一节课主要讲了博弈的几个原则. 1.不要选严格劣势策略: 2.理性选择造成次优选择: 3.要会换位思考: 4

hdu1856 Brave Game(博弈论)

应该是最基础的那种博弈论的题 (m+1)+多余 == n 如果没有多余,那么就后手赢了 #include<cstdio> int main() { int n; scanf("%d",&n); while(n--){ int x,p; scanf("%d%d",&x,&p); if(x%(p+1)==0 ) printf("second\n"); else printf("first\n")

Part.4【博弈论】

---恢复内容开始--- 不要问我为什么突然跳到Part.4,我懒得解释. 在蔡大神的论文+讲解和HZW的题库下,自己大概是明白什么是博弈论的皮毛了吧. 先说SG定理吧. 对于游戏中的状态,我们给每个状态定义一个必胜态和必败态.区别在于前者可以通过一次操作到达必败态,但后者无法做到(后者在一次操作后所能到达的状态全部都为必胜态) 接着引进SG函数,每个状态都有一个SG值,这个值由它所能到达的状态的SG值决定.(这里的所能到达的状态指的是经过一次操作能到达的状态,下同) SG值有以下性质: SG值

博弈论(转)

有一种很有意思的游戏,就是有物体若干堆,可以是火柴棍或是围棋子等等均可.两个人轮流从堆中取物体若干,规定最后取光物体者取胜.这是我国民间很古老的一个游戏,别看这游戏极其简单,却蕴含着深刻的数学原理.下面我们来分析一下要如何才能够取胜. (一)巴什博奕(Bash Game):只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个.最后取光者得胜. 显然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜.因此我们发

【博弈论】威佐夫博弈

威佐夫博弈     威佐夫博弈:有两堆石子,每次一个人可以两堆同时取相同数量的石子,也可以只取其中一堆的石子,最后谁取完谁获胜,请问先手还是后手胜? 对于学过一些博弈论基础的来说,我们需要找到那些能让先手必输的局势,那么由这些局势在规定范围内拓展的局势也是先手必输的局势(但在这里双方自由选取,不适用).我们可以得出一些局势使A必输:(0,0) (1,2) (3,5) (4,7) (6,10) (8,13) (9,15) (11,18) (12,20)……我们称这些局势为奇异局势 不难发现,如果我

HDU 5963 朋友 【博弈论】 (2016年中国大学生程序设计竞赛(合肥))

朋友 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description B君在围观一群男生和一群女生玩游戏,具体来说游戏是这样的:给出一棵n个节点的树,这棵树的每条边有一个权值,这个权值只可能是0或1. 在一局游戏开始时,会确定一个节点作为根.接下来从女生开始,双方轮流进行 操作.当一方操作时,他们需要先选择一个不为根的点,满足该点到其父亲的边权为1; 然

博弈论之入门小结

经过几天的学习和刷题,总算对博弈论的基础懂了一些,学习过程中参考了以下两位的总结: 博弈总结        博弈论题目列表 下面列出一些基础博弈的结论定理(证明过程略): (一)巴什博弈(Bash): 一个堆中有n个物体,两人轮流取,每次至少取1个,至多取m个,最后取完者胜. 取胜法则:令n=(m+1)*r+s  (s<=m,r为任意自然数),先取者要想取胜,则要求第一次取时必须取s个. (二)威佐夫博弈(Wythoff): 两个堆中各有若干个物品,两人轮流从某一堆或从两堆中同时取同样多个物品(