HDU-4315 Climbing the Hill
Climbing the Hill
階梯博弈
一開始覺得可以以後面那個緊跟前面那個的操作,就聯想到了階梯博弈,但是一想到階梯博弈只能一個個走,這個能全部一起走,就放棄了這個想法,沒想到最後居然真的是階梯博弈
我們將所有的人從後往前兩兩分組,如果最前面有一個是落單的話,就假設有一個石子在終點處與它組隊。
兩兩分組之後,我們可以發現,如果前面的人移動了,後面的人也可以跟著移動,因此相較於階梯博弈,一組內,兩個人的之間的格子數可視為階梯博弈中奇數臺階的石子數。而組與組之間的格子數可視為偶數臺階的石子數,並不會對答案造成影響。
對於分組:假設人的編號為 1 到 n
對於 n 為偶數的情況: \((a_1,a_2)\)
對於 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; }