只有一堆n個物品,每次至少取a個,最多取b個
問題可分為
1.最後取完者勝 (面臨(a+b) * k個物品的人必敗)
2.最後取完者敗 (面臨(a+b) * k+a個物品的人必敗)
因此當兩個都極其聰明的人博弈時,就看有多少個物品,自己先手取了之後能否讓對手面臨必敗點
對於最後取完者勝的情況
對取物品方面又可分為
①最後當物品數小於a的數量就不能再取了
②最後當物品數小於a的數量還能再取最後一次
通過考慮 總物品數 n=(a+b)*k+c 通過c的範圍來判斷是先手勝還是後手勝
若是情況①,先手的目的就是想給對手留下(a+b)*k個物品
(1) 當c==0時 ,即n=(a+b)*c時,先手沒辦法給對手留下(a+b)*k個物品,後手勝
(2) 當1<=c若是情況②,先手的目的也是想給對手留下(a+b)*k個物品
(1) 當c==0時 ,即n=(a+b)*c時,先手沒辦法給對手留下(a+b)*k個物品,後手勝
(2) 當1<=c對於最後取完者敗的情況
對取物品方面又可分為
①最後當物品數小於a的數量就不能再取了
②最後當物品數小於a的數量還能再取最後一次
通過考慮 總物品數 n-a=(a+b)*k+c 通過c的範圍來判斷是先手勝還是後手勝
只需要將最後取完者勝討論的情況中的n換為n-a即可,討論的c的範圍與結論都一樣
這類題目就是通過判斷總物品數來判斷先手勝還是後手勝
有若干堆一定數量物品,兩人依次從任意堆中拿任意數量物品,每次至少取1個,面臨奇異局勢的人必敗
**奇異局勢:**所有堆的異或和為0
若當前不是奇異局勢狀態,如何將他變成奇異局勢狀態?有多少種方案數?
先算出當前所有堆的異或和值sum,再用這個值與每一堆的值進行異或,如
令 res=x1(+)sum 由公式 a(+)b(+)c(+)c = a(+)b
因此res就是除了x1那一堆其餘所有堆的異或和,因此只需要在x1>res的前提下
將x1堆的值減到res即可(res(+)res=0)。所以,這就得到了一種方案,通過遍歷所有的堆,當x>res時就是一種方案,最終可求得總方案數
例題:洛谷p1247取火柴遊戲
**
#include
#include
#include
#include
#include
#define ll long long
using namespace std;
intmain()
if(sum==0)
//如果異或和為0,說明先手面臨奇異局勢,必敗
printf
("lose\n");
else
//如果異或和不為0,則先手想通過改變某一堆的數量讓局面變為奇異局勢
}printf
("%d %d\n"
,v,u+1)
;for
(int i=
0;i1;i++
)printf
("%d "
,a[i]);
printf
("%d\n"
,a[n-1]
);}}
尼姆博弈(巴什博奕)
尼姆博弈 有三堆各若干個物品,兩個人輪流從某一堆取任意多的物品,規定每次至少取乙個,多者不限,最後取光者得勝。這種情況最有意思,它與二進位制有密切關係,我們用 a,b,c 表示某種局勢,首先 0,0,0 顯然是奇異局勢,無論誰面對奇異局勢,都必然失敗。第二種奇異局勢是 0,n,n 只要與對手拿走一樣...
博弈(巴什博奕 尼姆博弈)
1.巴什博奕 一堆 n個物品 兩人輪流從中取物品每人至少拿乙個最多拿m個將這堆物品最後取完的是winner先手勝利條件 n m 1 0 誰面對 m 1 k的情況誰就輸了 k為正整數 include int main return 0 2.尼姆博弈 三金和敵人決戰了!對手是一名和三金同樣強大帥氣的玩家...
NYOJ135 取石子(二)尼姆博弈 巴什博奕
尼姆博弈和巴什博奕的結合 題目思路 每一堆的必勝狀態是 m n 1 然後對每一堆的最優解進行異或,如果是非平衡狀態則先手必勝,否則先手必敗。2017年8月23日23 32 33 nyoj135 nimm bash ac include include include include include ...