Loading

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 所在的位置真的对博弈结果没有影响吗?

  1. king 在小组的后一个位置,跟随着上述的策略,显然是没有影响的

  2. king 在小组的前一个位置 且 k > 2 时,在最终的状态下,必然会出现 \(a_{k-2} = 0\) 的情况,此时的玩家,必然不可能将 \(a_{k-1}\) 直接放到 0 的位置上去,因为对手肯定直接就赢了;因此此时的玩家必然会将其置为 1,逼迫对手去将这个置为 0。这个操作下,先前是必胜态的玩家仍是必胜态,并不影响

  3. 补充第 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;
}
posted @ 2022-05-18 16:38  dgsvygd  阅读(19)  评论(0编辑  收藏  举报