今天咱们来聊一聊另外一种博弈--尼姆博弈,这一种博弈能够说是巴什博弈的一种变体,巴什博弈中“石子”的堆数为1堆,而在利姆博弈中“石子”的堆数为n堆,还有在尼姆博弈中取石子的规则也发生了变化,前一种博弈中取石子的数量限定在[1,L],然后一种取石子的数量能够为任意数(但不能不取,并且还不能超过这一堆石子的总数),一样也是两人轮流来取,先取完者获胜。ios
下面咱们进行一下分析:spa
(1) 先假设只有两堆石子,当二者数量相同的时候,先手必败(先手从一堆中取a个石子,后手模仿先手从另外一堆也取a个,最后必定是先手败);当二者数量不相等时,先手能够经过取石子将两堆石子变为的数量变为同样,这样,后手就面临必败态了。
.net
综合来看的话:当谁面临“两堆石子的数量相等”这一状态时,谁就必败。code
(2) 如今咱们将状况推广到普通状态,咱们先假设存在两堆石子a=7,b=5。这是两堆数量不一样的石子堆,经过二进制拆分能够将他们化为:111 101,也就是(4+2+1)(4+1),咱们如今能够将其视为5堆石子,其中有两堆数量为4,两堆数量为1的石子,也就是说,谁面临这种状况,谁就必败。而最后一堆谁将它一次性所有拿走,谁就是赢家。而经过二进制拆分能够将两堆数量分别为四、1的石堆归零不计。而经过异或这一操做正好能够达到这一要求。
blog
由上获得结论:对每一堆石子的数量进行异或,最终的值为0时(尼姆和),先手必败,反之,先手必胜。ci
典型例题:get
题意:n堆石子,两我的轮流取,先取完者获胜。it
题解:尼姆博弈的模板,直接套用。io
代码:模板
#include<iostream> #include<algorithm> #define ll long long using namespace std; int main() { ll n,t; while(cin>>n) { ll sum=0; cin>>sum; for(int i=1; i<n; i++) { cin>>t; sum=sum^t; } if(sum==0) cout<<"No"<<endl; else cout<<"Yes"<<endl; } return 0; }
类似题目推荐 :HDU - 2176 HDU-1850