基本常见的路人皆知的博弈
巴什博奕(Bash Game);威佐夫博奕(Wythoff Game);尼姆博奕(Nimm Game)。 此外,还有翻硬币,删边等。 当然,不乏一些变态数学题。
基础博弈高中是学习过,但是过于基础,现在强化博弈方面。
一般的博弈最后取者胜。自然还有最后取者输的。
博弈的输赢关键在于找到XXX态(必输、必赢、S态?T态之类的东西)。然后看能不能自己面对必赢态,然后取后把必输态留给对手。
注意:一般的博弈题不能普通搜索(直接搜索是否可以再轮到自己时达到某状态)解决,因为两个玩家都是高智商,双方都是采取最优解。
现在的状态应该是:自己可以将面对的状态变为必败,则为必赢;若不能则为必败。 若从一张图上看,就是G状态后序节点中有一个必败节点,则它自己为必胜节点.....然后可能就需要SG函数。
【参考】
博客经典讲解:http://blog.csdn.net/acm_cxlove/article/details/7854526 (cxlove)。
SG函数详细:https://www.cnblogs.com/ECJTUACM-873284962/p/6921829.html
SG函数通俗证明:http://blog.csdn.net/strangedbly/article/details/51137432
二分图博弈:https://www.cnblogs.com/jffifa/archive/2011/12/17/2291069.html (2018-3-25补充)
著名进阶讲解:Thomas S. Ferguson(群里有)。
等做够了题,把难度分级后再上题。
待续-------------------------------------------------------------------------
【基础博弈】
题目大意:
N个硬币排成一排,已知是正面(H)还是反面(T)。现在两个人轮流翻,每次只能选择一枚正面(H)的硬币翻到反面,
同时可以选择一枚左边的硬币翻转(此时不管正反都可以翻)。 没有可以翻的人输。
思路:
我们规定,只有第i个硬币正面向上,则为状态i,全部向下为0。那么状态i可以变为状态0,1,2....i-1。分别表示0:翻转第i个,不翻转左边的;
1:翻转第i个,顺便把第1个也翻转...
但是情况不单单是只有一枚i硬币朝上。但是不重要,如果第j<i枚也朝上,那么翻转第i个,顺便翻转第j个的情况就是j^j=0就行了。
所以状态X可以变为0,1,2,,,,x-1,这和Nim的规则是一样的。
#include<cstdio> #include<cstdlib> #include<iostream> #include<algorithm> using namespace std; const int maxn=11000; char chr[maxn]; int main() { int N,Xor,i; while(~scanf("%d",&N)){ scanf("%s",chr+1); Xor=0; for(i=1;i<=N;i++){ if(chr[i]=='H') Xor^=i; } if(Xor) printf("Alice\n"); else printf("Bob\n"); } return 0; }