Nim游戏·改(博弈论)
2017-08-28 15:37
176 查看
Nim游戏·改(nim.c/cpp/pas)
8.28思路:
对于一个平等博弈局面X,若它走下一步能达状态集合Y,则:
SG(X) = mex (SG(t)) t∈Y
其中mex(S)为最小的非负整数v满足v !∈ S
首先对于一个终止局面X,也就是说X没法走下一步了,显
然SG(X) = 0。也就是SG(0) = 0.
用这类博弈问题的基础处理方式,即把各游戏独立开,各自求SG后再异或起来。
这题中一堆石子即一个独立的游戏,可以用归纳法证明:
一个有额外机会的石子数为i的一堆,若i为奇数,则SG值为i+1;
若i为偶数,则SG值为i-1。于是O(1)得到每一堆的SG值后异或起来即可。
怎么推呢? SG(0) = 0
SG(1)* = mex (SG(t)) = mex (SG(0), SG(1)**) 因为可以不取所以 SG(1)也是其中一个后继状态
SG(0) = 0, 要注意这里的 SG(1) * 与SG(1) * * 并不相同,SG(1)并没有用过那次不取的机会,SG(1) * 已经没有这个机会了
意思就是说SG(1) * 的后继状态有SG(1),但是SG(1) * * 的后继状态就没有SG(1)了
所以 SG(1) * * = mex (SG(t)) = mex (SG(0)) = 1;所以 SG(1) * = 2;
(下面我们用 * 代表还有不取的机会, * * 代表没有不取的机会)
SG(2)* = mex (SG(t)) = mex (SG(0),SG(1) * ,SG(2)* * )
SG(0) = 0,SG(1)* = 2;同理SG(2) * 与SG(2)* * 并不相同 SG(2) * * = mex (SG(t)) = mex (SG(0), SG(1)**) = 2
所以 SG(2)* = 1;这样推下去就会得到结论。
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int n, x, y; int main(){ freopen("nim.in", "r", stdin) ; freopen("nim.out", "w", stdout) ; int T; scanf("%d", &T); while( T-- ){ x = 0; scanf("%d", &n); while( n-- ){ scanf("%d", &y); x ^= y&1 ? y+1 : y-1; } x ? puts("A") : puts("B"); } }
相关文章推荐
- NJUST 谁才是最强战舰!(博弈论-Nim游戏)
- [学习笔记] (博弈论)Nim游戏和SG函数
- bzoj1022.小约翰的游戏John(博弈论 NIM游戏)
- 博弈论(一):Nim游戏
- 【转】博弈论--取物品和Nim游戏
- 博弈论—Nim游戏
- BZOJ3105: [cqoi2013]新Nim游戏 博弈论+线性基
- 51nod 1069 Nim游戏(博弈论)
- 博弈论(一):Nim游戏
- 51nod 1069 Nim游戏 (博弈论)
- bzoj 3105: [cqoi2013]新Nim游戏 博弈论+贪心(拟阵)+线性基
- [BZOJ1022][SHOI2008][博弈论][Nim游戏]小约翰的游戏
- 博弈论(一):Nim游戏
- 博弈论 取石子
- HDU 1527 取石子游戏(博弈论)
- 博弈论入门小结
- 博弈论--取石子游戏
- 基于博弈论的大学生社群合作行为研究申报书(C写一个博弈软件)
- 博弈论-取石子问题
- 【博弈论】poj2484 A Funny Game