博弈,搞起!
小知识点
HDOJ2176 取(m堆)石子游戏 [输出第一步走法]
若给出的是必胜状态:a1^a2^.......^an=k,(其中k不为零),那么我们的目的是要把必胜状态
转化为必败状态从 而使得先手胜利。若a1^a2^...^an!=0,一定存在某个合法的移动,将ai
改变成ai'后满足a1^a2^...^ai'^...^an=0。若a1^a2^...^an=k,则一定存在某个ai,
它的二进制 表示在k的最高位上是1(否则k的最高位那个1是怎么得到的)。这时ai^k<ai一定
成立。则我们可以将ai改变成ai'=ai^k,此时a1^a2^...^ai'^...^an=a1^a2^...^an^k=0。
HDOJ1907&&POJ3480&ZOJ3113 John [ANTI-SG]
必胜策略:1.sg值为0 且 全为孤单堆;
2.sg值不为0 且 不全为孤单堆;NP暴力打表||找规律
HDOJ1525&POJ2348 Euclid's Game [找规律博弈]
注意第一次出现a/b>1的位置为必胜
打表发现奇偶性规律
HDOJ1404 Digital Deletions [SG博弈](暴力打表,NP定理)
老实说,这个表不太好打。从P->N一种是在让某一位增加;另一种是在后面补0;
裸求sg值
HDOJ3032 Nim or not Nim? [找规律]SG打表
重点是sg函数的求法,把一堆变成两堆,有嵌套的感觉。
HDOJ1729 Stone Game [SG博弈]
这题我开始打了个表,,什么规律都没找出来,还是得靠分析,,可我不会啊。。。。
我的理解:可以先模拟一下,初始为(27,2),子递归状态为(4,2)然后返回2,结束。
然后我从前往后推,A先拿2个,变为(27,4)状态,然后无论B怎么拿都无法拿完,所以B很保守的只拿一个,变为(27,5)状态,然后A轻松拿完;所以A获胜了。
所以我的理解是子递归状态返回值的意义在于 先手能否成功到达必败点,让后手必败。
那么对于这题对于每一堆,放石子放满就想当于满的时候取s-c个,反向只是让我理解题意更深。
首先我们知道(S,S)这个局面是必败局面。
对于每一堆能加的数量有限,而当c的值(大于或者等于)D=sqrt(s) 或者 D=sqri(s)+1的时候就可以一次完成,就是说可以从当前局面到达(S,S)的局面,所以当前局面是必胜局面。
而这种情况下,你能造成的局面有集合A={0,1,2,...,s-c-1};因为你可以去s-c,s-c-1,s-c-2,.....,1;那么对应mex(x)函数(即A中未出现的最小的一个数字),那么自然该局面的SG值就是s-c了;
另外当c的值小于D的时候,是不可能一下子加满的,因为c*c+c绝对是小于s的;那么小于D的局面一定能够是必输的吗?很显然不是的。
对于(S,D-1)这个局面,一定是必输,因为他能到的局面都是必胜!现在c小于D,那么如果(S,C)这个局面能到(S,D);就代表这个局面是必胜的。所以现在SG值要在新集合(D,C)中求,而求法与上面的相同求新的D,所以可以用递归函数:当C>D时,返回(S-C)
差不多就是这样。
其实D = sqrt(s);这里算是个加速,要不然就要:while(d*d+d < S) d++;这样会很慢的。
思路:这题明显的sg函数。可惜我纠结了半天没想起思路来。设当前的箱子容量为si,求出一个t满足:t + t * t < si,若是当前箱子里有ci颗石头,
1、ci > t 则必胜;
2、ci == t 则必败;
3、ci < t不可立即断定,将t作为si递归调用函数。
当满足ci > t时,return si - ci 作为当前状况的sg值。因为:
当ci在si点时,为有向图的端点,出度为0,也就是必败点,所以sg值为0;
当ci 位于si - 1时,ci的端点可能的sg值构成的凑集为{0},所以当前sg值 为1;
当ci 位于si - 2 时,ci的端点可能的sg值构成的凑集为{0, 1},所以当前的sg值为2;
可得,ci地点地位的sg值为si - ci;
[TopCoder]SRM 561 DIV1
题意:给你n<=50个不相交的圆(可能包含)。Alice 和Bob博弈,Alice先手,每次每人都可以选择一个没有红点的圆,在圆内放置一个红点,最后没法放红点的一方失败。
算法分析:圆与圆没有相交,故可以把每个圆看成一个结点,直接包含看成点与点之间的边,于是得到一个森林。原题变成在这个森林里博弈,每次选取一个结点,可以干掉他和他的所有祖先结点,干掉最后一个点的获胜。
首先我们来考虑每颗树的sg函数。我们可以选择这棵树上任意一个结点操作,去掉这个结点以及其祖先结点后剩下的树的sg函数取异或便是当前操作所得状态的sg值,去掉这些sg值,剩下sg值的最小值即为这棵树的sg函数(看不懂的先好好学学博弈论)。求出每颗树的sg函数,最后取异或便是最终的sg函数,结果不等于0先手胜否则后手胜。
starcase
HDOJ3389 Game [Staircase Nim]变形
要注意这类博弈的特点:一定是奇堆移动到偶堆,偶堆移动到奇堆。
题意:
有N堆石子,每堆石子都有一定的石子数,Alice和Bob轮流玩一个游戏,游戏的规则是,每回合一个人可以选择1-n堆石子中的某一堆进行操作,操作是:假设选择操作的那堆石子的编号为A,现在还要选择一堆石子B,满足B<A && (A+B)%2==1 && (A+B)%3==0,然后可以将A中至少一颗石子移到B中去,第一个不能进行合法操作的人输,问谁能赢。
思路:
这是一个阶梯博弈的题目,首先我们可以发现,只有1 ,3 ,4 三个数是没有前缀的, 也就是terminal状态,其余的每个状态我们都可以计算出每个编号到这几个terminal的步数(当然有的编号的步数并不唯一,但是奇偶性是唯一的)。接下去我们就会发现,每次从一个奇数步的点,一定是要移到到 一个偶数步的点上去,也就是说每次只能移到奇数步,这个通过编号自身的奇偶性就可以证明了。这样就转化为了阶梯博弈的类型了,我们只需要关注奇数步编号出的石子的数量就可以了,如果奇数步编号处的石子的Nim和为0,则必败,不为0则必胜。接下去我们就简单地证明一下这个策略:如果移动的是奇数步位置的石子,则一定是移动到偶数步的位置,这时候我们只需要按照Nim博弈的必胜策略进行游戏就可以赢;如果移动的是偶数步数编号位置的石子,则移动是移动到奇数步的位置,这时候我们只需要将刚刚移动过来的石子移动到下一个偶数步位置,原来的Nim局面并没有变化,变化的只是偶数步石子的数量。这样我们就证明了原游戏可以转化为Nim游戏。
POJ1704 Georgia and Bob [阶梯博弈] (下面一题是这个的加强版,直接把这种最纯粹的看做模型)
我们把棋子按位置升序排列后,从后往前把他们两两绑定成一对。如果总个数是奇数,就把最前面一个和边界(位置为0)绑定。
在同一对棋子中,如果对手移动前一个,你总能对后一个移动相同的步数,所以一对棋子的前一个和前一对棋子的后一个之间有多少个空位置对最终的结果是没有影响的。
于是我们只需要考虑同一对的两个棋子之间有多少空位。
这样一来就成了N堆取石子游戏了.
HDOJ4315 Climbing the Hill [阶梯博弈] (有待提高)
这题压力山大,看了好久:
此题的简化版本是不考虑King的存在,双方一直走到不能走的一方为负。此时的解法是根据人数的奇偶性:把人从上顶向下的位置记为a1,a2,...an, 如果为偶数个人,则把a(2i-1)和a(2i)之间的距离当做一个Nim堆,变成一共n/2堆的Nim游戏;如果为奇数个人,则把山顶到a1的距离当做一个Nim堆,a(i*2)到a(i*2+1)的距离当做Nim堆,一共(n+1)/2堆。
考虑King的情况和上述版本几乎一致,只要把King当作普通人一样处理即可。除了两种特殊情况:1. 当King是第一个人时,Alice直接胜 2. 当King是第二个人且一共有奇数个人时,第一堆的大小需要减1。
谁最后把红球移出谁就赢!
分析:
1、n 为偶数时:问题简化一下,假设全都是黄球,谁把最后一个球移出谁就赢
(a1,a2) (a3,a4) …… ( a(2*n-1) , a(2*n) ) ……(a(n-1),an)其中第 i 个球与第 i+1 个球是相邻的,i 为基数,谁面对这个状态谁就必输。
理由很简单,先手移动第 i 个球,后手移动第 i+1 个球,使之仍然保持必赢状态。
回到原问题谁先移出红球谁就赢,假设红球不是第一个球(因为第一个球Alice直接就赢了)
很显然如果红球在偶数位置后手必赢,如果在基数 i 位置,则只需将 第 i-1 个球移到第一个位置就ok了。
所以与红球位置无关。至于产生这个状态(a1,a2) (a3,a4) …… ( a(2*n-1) , a(2*n) ) ……(a(n-1),an),那么就是简单的 Nim问题了
2、n 为基数时:假设红球是第1、2个球。
(a1) (a2,a3)(a4,a5)…… (a(2*n),a(2*n+1)) …… (a(n-1),an) 谁面对这个状态必赢!理由是先手直接把 a1 取走然后就变成上面的情况了,
如果红球在第 2 个位置那么就是必输状态。
与staircase的联系:对于这个题目,从后向前两两划分成一组,组内相当于奇数阶梯上的石子,组间相当于偶数阶梯上的石子,移动组内的前面石子一定能够通过移动当前组的后面石子相同步数达到平衡态,移动组内后面的石子一定能够通过移动其他组后面石子达到平衡态,具体因为King的原因需要处理细节,上面已经说清楚了,不再赘述。
翻硬币游戏
HDOJ3537 Daizhenyang's Coin[翻硬币游戏]SG打表 (待解决)
这题表我是打出来了,规律没找出来(注意还要对编号排序判重)
HDOJ3951 Coin Game [找规律]
题意:给你n个硬币排成一圈,编号1-n,只能翻转连续的1~k个的硬币。翻最后一枚硬币者赢。
思路:博弈
1) 若k=1,则一次只能去翻一枚,奇数先手赢,偶数后手赢。
2)若k>1:
a: 先手一次翻完,先手赢;
b: 先手不能翻完,第一次必定断环。只要后手一次翻完,或将其分为相等数量的两段,
之后先手怎么操作后手就怎么操作,后手必赢。
树&&删边
HDOJ3094 A tree game [有向无环树形图SG博弈]最基础的删边
HDOJ3197
Game [树形SG博弈]砍树
树的删边游戏,把多棵树的根异或起来就行了
HDOJ3590 PP and QQ [树的删边游戏+ANTI-SG]
先手必胜当且仅当:(1)游戏的SG函数不为0且游戏中某个单一游戏的SG函数大于1;
(2)游戏的SG函数为0且游戏中没有单一游戏的SG函数大于1。
POJ3710 Christmas Game [无向图删边]
Tarjan算法找出环,处理环之后,便是经典的删边游戏。
拥有奇数条边的环可简化为一条边,偶数条边的环可简化为一个节点。