HDU-4315 Climbing the Hill(阶梯博弈变形)

来源:互联网 发布:百合网淘宝女店主 编辑:程序博客网 时间:2024/04/29 09:56

题意:

在山上有n个人,每个人编号是1~n,这些位置只能同时被一个人占据,但是山顶可以同时被多个人占据,距离山顶第k近的是King,现在Alice和Bob开始向上送人,条件是不能跨越前面最近的人,问在Alice先手,双方最优的条件下谁能把King送到山顶获胜。

思路:

一道阶梯博弈变形的题,POJ-1704是一道朴素的阶梯博弈题目,但是这题与之有区别:每个点都可以移动到山顶,如果没这个条件再稍微修改一下,那么这题就会变成一道普通的阶梯博弈。

对于本题,从后向前两两划分成一组,组内相当于奇数阶梯上的石子,组间相当于偶数阶梯上的石子,移动组内的前面石子一定能够通过移动当前组的后面石子相同步数达到平衡态,移动组内后面的石子一定能够通过移动其他组后面石子达到平衡态,如果这么考虑的话这题就是阶梯博弈(详)。

而本题问题又在于谁能掌握主动权让自己移动King到山顶的问题,与第k在其组内前后无关(这儿可以自己脑力实现一下,只要你处于必胜态那么肯定能保证自己移动King到山顶)。

另外需要单独考虑两个点,k == 1时,Alice必胜。k == 2时,我们会进行正常的分组尼姆堆,但是当n为奇数的时候,第一个点要与到山顶组成一堆,但是Alice和Bob都不愿意将第一个点的人移动到山顶0(此处需要思考),所以第一个尼姆堆的数量要-1,然后我们再做尼姆博弈就好了。


代码:

#include <bits/stdc++.h>using namespace std;int a[1005];int main(){int n, k, ans;while(cin >> n >> k){ans = 0; a[0] = -1;for(int i = 1; i <= n; ++i) cin >> a[i];if(k == 1) {puts("Alice"); continue;}if(n&1 && k == 2) ++a[0];for(int i = n; i >= 1; i-=2)ans ^= a[i]-a[i-1]-1;if(ans) puts("Alice");else puts("Bob");}return 0;}


继续加油~