今天咱們來聊一聊另外一種博弈--尼姆博弈,這一種博弈能夠說是巴什博弈的一種變體,巴什博弈中「石子」的堆數爲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