HDU-4315 Climbing the Hill
Climbing the Hill
阶梯博弈
一开始觉得可以以后面那个紧跟前面那个的操作,就联想到了阶梯博弈,但是一想到阶梯博弈只能一个个走,这个能全部一起走,就放弃了这个想法,没想到最后居然真的是阶梯博弈
我们将所有的人从后往前两两分组,如果最前面有一个是落单的话,就假设有一个石子在终点处与它组队。
两两分组之后,我们可以发现,如果前面的人移动了,后面的人也可以跟着移动,因此相较于阶梯博弈,一组内,两个人的之间的格子数可视为阶梯博弈中奇数台阶的石子数。而组与组之间的格子数可视为偶数台阶的石子数,并不会对答案造成影响。
对于分组:假设人的编号为 1 到 n
对于 n 为偶数的情况: \((a_1,a_2)\),\((a_3,a_4)\),...,\((a_{n-1},a_n)\)
对于 n 为奇数的情况: \((a_0,a_1)\),\((a_2,a_3)\),...,\((a_{n-1},a_n)\)
以上其实我在看其他题解的时候也会产生一个疑惑,king 所在的位置真的对博弈结果没有影响吗?
-
king 在小组的后一个位置,跟随着上述的策略,显然是没有影响的
-
king 在小组的前一个位置 且 k > 2 时,在最终的状态下,必然会出现 \(a_{k-2} = 0\) 的情况,此时的玩家,必然不可能将 \(a_{k-1}\) 直接放到 0 的位置上去,因为对手肯定直接就赢了;因此此时的玩家必然会将其置为 1,逼迫对手去将这个置为 0。这个操作下,先前是必胜态的玩家仍是必胜态,并不影响
-
补充第 2 点的情况:当 king 处于小组的前一个位置,但是 king 前面并没有 2 个人,即 n 为奇数 且 \(k = 2\) 的情况:易分析,第一个人,操作者只能将其移动到 1,不能移动到 0,理由与 2 中一样。因此对于第一个棋子,他的最终结束状态是 1,而不是 0,所以其 sg 应该是 \(a_1 - 1\)
综上:
-
当 \(k = 1\) 的时候,显然不需要博弈,先手必胜
-
当 n 为奇数,且 k = 2 的时候,第一个组的 sg 值应该为 \(a_1 - 1\),而不是通解中的 \(a_1\),所以要减一
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 1010;
int num[maxn];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int n, m;
while(cin >> n >> m)
{
for(int i=1; i<=n; i++) cin >> num[i];
if(m == 1) {cout << "Alice" << endl; continue;}
int ans = 0;
if(n % 2 == 0)
{
for(int i=1; i<=n; i+=2)
ans ^= (num[i+1] - num[i] - 1);
}
else
{
ans = num[1];
if(m == 2) ans--;
for(int i=2; i<=n; i+=2)
ans ^= (num[i+1] - num[i] - 1);
}
if(ans) cout << "Alice" << endl;
else cout << "Bob" << endl;
}
return 0;
}