1. 程式人生 > 其它 >HDU-4315 Climbing the Hill

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;
}