組合賽局

北一女中 鄭允臻

自我介紹

  • 北一女中高三
  • 各個OJ handle:hhhhaura (可能有4~20個h)
  • 因為之前欠8e7人情,所以今天來還債
  • 裝弱是強者的特權,所以我沒資格裝弱

WARNING!

  • 內容98.87%抄襲2022 IOICamp的講義
  • 譴責劉澈造謠,我沒有要講hackenbush

今天希望你能夠學會

組合賽局基本介紹

PART ONE

什麼是組合賽局?

  • 賽局理論的一個分支
  • 兩位玩家對戰,雙方輪流操作
  • 資訊完全公開
  • 操作與結果具有決定性(不含隨機成份)
  • 結果:輸/贏/平手

Game Graph

DAG ➡ 動態規劃

組合賽局分類

  1. 依結構分類
  2. 依玩法分類

 

依結構分類

玩家合法操作異同 有偏(Partial) 無偏(Impartial)
是否有限步內結束 無環(Loopfree) 有環(Loopy)

互為補集

依玩法分類

  • 標準(Normal):輪到該回合時,無法操作者輸
  • 匱乏(Misère):輪到該回合時,無法操作者贏

並沒有構成所有賽局!

競程裡面遇到的賽局

八成以上都是標準無偏無環賽局!

對於一個組合賽局:

  1. 先手有必勝策略
  2. 後手有必勝策略
  3. 雙方皆有必勝策略

考慮無環賽局

  1. 標準無環賽局無平手
  2. 匱乏無環賽局無平手

將遊戲規則壓縮進狀態

無偏無環賽局Game graph

關於有偏賽局的Game Graph

在節點上多一個維度!

(0, A)

(1, B)

(1, A)

(0, C)

(1, D)

(0, E)

是DAG的話又可以DP了?

關於匱乏賽局的Game Graph

把原圖上的終點再連出去一個虛點!

A

C

B

D

便得跟標準賽局一樣了?

欸?那幹麻要分那麼多類!

不是就多定義一個維度轉換成圖就好了嗎?

不用賽局理論就可以做的賽局題?

標準無偏無環賽局1

PART TWO

賽局和、型別、等價賽局

The Subtraction Game

有N顆石頭,兩人輪流拿,每次可以拿走1 ~ 3顆,拿到最後一顆的一方贏。請問先手還後手必勝?

1 \leq N \leq 10^{18}
  • 無偏:每個人的操作相同
  • 無環:石頭必定在有限次數拿完

怎麼做?

S(x)=\left\{ \begin{array}{rcl} -1, & & \forall y \in [x - 3, x - 1],S(y) = +1\\ +1, & & otherwise\\ \end{array} \right.

怎麼做?

x 0 1 2 3 4 5 6 7 8
S(x) -1 +1 +1 +1 -1 +1 +1 +1 -1

有規律!

怎麼做?

S(x)=\left\{ \begin{array}{rcl} -1, & & x \ mod \ 4 \ = \ 0\\ +1, & & otherwise\\ \end{array} \right.

S(x) = 1 時:

讓輪到對方時剩下4k顆石頭

賽局合

  • G1 + G2
  • 每次選其中一個賽局操作
  • eg. 西洋棋 + 象棋

當遊戲規則壓縮遇到賽局合

以有偏賽局為例:

  • 兩個賽局 → (A, B, 0/1)
  • 三個賽局 → (A, B, C, 0/ 1)
  • N個賽局 → (A, B, C, ....., 0/ 1)

太複雜了吧?!

因此才要把賽局分類探討

(無偏無環)型別

  • N(Next player win)先手獲勝
  • P(Previous player win)後手獲勝

如果一個賽局盤面可以轉移到型別為P的盤面,代表他的型別是N;反之,如果他只可以轉移到型別為N的盤面,代表他的型別是P。

等價賽局

給定兩個賽局G1, G2,如果對於任意賽局HG1+HG2+H的型別皆相同,那麼我們稱這兩個賽局等價G1=G2

  • 不要求兩個賽局可以轉移到的賽局必須等價
  • 所有賽局都可以轉換成任一等價賽局

G2的型別是P,那麼G1+G2=G1

  • 本來在G1有優勢的玩家看見對方玩G2→去玩G2
  • G1的優勢玩家能夠保持優勢→G2不影響型別

G1G2都是P,則G1=G2

  • 對任何一個賽局H都有H+G1=H=H+G2,因此G1=G2
  • 所有型別為P的賽局都是同一種賽局(零賽局)

標準無偏無環賽局2

PART THREE

酷酷定理:NIM、SG Theorem
 

NIM game

N堆石頭,分別是a1,a2,...,aN顆,兩人輪流拿,每次可以從其中一堆拿走任意堆但是至少一顆石頭,無法拿的人就輸了,請問先手必勝還是後手必勝。

 

N\leq 10^5, a_i\leq 10^9

好像很難...

特徵值

X=a_1\oplus a_2 \oplus...\oplus a_N

Bouton's Theorem

此遊戲先手必勝(型別N),若且唯若X ≠ 0。同理,此遊戲後手必勝(型別P),若且唯若X = 0。

為什麼?

若能說明以下兩件事,則可證明此定理:

  1. X=0的狀態無法走到其他X=0的狀態,且對於結束局面,X=0
  2. X0的狀態必定可以走到一個X=0的狀態。

X=0的狀態無法走到其他X=0的狀態,且對於結束局面,X=0

後半部:trivial

前半部:

X' = X \oplus a_i \oplus (a_i - k) = 0 \oplus (a_i \oplus (a_i - k)) \neq 0

X0的狀態必定可以走到一個X=0的狀態

目前特徵值為X的最高bitb

則必定有至少一個aib以上的bit

因此將aiX必定<ai

ai拿掉ai-(aiX)顆石頭

則X=Xai(aiX)=0

故得證。

 

NIM sum

特徵值為X的Nim遊戲G,等價於僅有一堆數量為X的Nim遊戲H

H + H = 0, G + H = 0\\ G = G + (H + H) = (G + H) + H = H\\

打打字?

Sprague-Grundy Theorem

標準無偏賽局的終級定理!

對於任一一個標準無偏賽局,必定有一個與其等價的一堆Nim遊戲,而此堆Nim遊戲的大小,稱作SGValue

Chose NIM

給定一個N個元素的集合

\{a_1, a_2, ..., a_N\}

先手從中挑選出一個數字   ,接下來便成了一個僅有一堆數量    的Nim遊戲。此時由後手取石子,接著依照Nim遊戲的規則繼續遊玩。

a_i
a_i

MEX principle

給定一個集合s={a1,a2,...,aN},若從中選擇一堆玩僅有一堆數量為aiNim遊戲GChoose Nim),那麼此賽局會等價於一堆數量為mex(s)Nim遊戲H

MEX:集合中最小沒有出現的非負整數

為什麼莫名其妙就跟MEX扯上關係了呢?

先說明G + H = 0

b=mex(s)

若是先手選擇G並選擇了一堆石頭c那麼cb ,則X = bc0,先手必敗。

 

先說明G + H = 0

若先手選擇H則b' < b:根據mex的定義,後手必定可以選擇一堆石頭c=b,此時特徵值為0,先手必敗。

等號兩邊都加上HG+(H+H)=H

標準無偏無環賽局等價Nim

說明一個盤面必定等價一堆Nim

標準無偏無環賽局等價Nim

Game Graph上沒有出度的點→P型別

標準無偏無環賽局等價Nim

數學歸納法:            

 

G = \{G_1, G_2, ... , G_k\} \\ H = \{*n_1, *n_2, ..., *n_k\}

Mex principle→H=*m, m = mex(H)

標準無偏無環賽局等價Nim

只要說明G=H就可以了!

(G + H = 0)

標準無偏無環賽局等價Nim

G + H = 0

無論先手動G或H

後手都可以動另外一個遊戲使特徵值為0

結論:

  1. 一個標準無偏無環賽局等價於一堆Nim
  2. 用Nim sum求賽局和
  3. 在game graph上用mex principle轉移

你和你的朋友在玩一個遊戲。你們一共有N條紙帶,每條紙帶有   格,每次你們輪流選一條紙帶上的一個空白格畫上圈圈,畫出三個連續圈圈的那個人就贏了(不需要三個都由他來畫)。在雙方都是絕頂聰明的情況下,問你結果會是先手贏、後手贏,或是平手?

a_i
T\leq 100, N\leq 10000, a_i \leq 1000

剛剛說無偏無環必定沒有平手?
難道這不是無偏無環?

有一個M * N的棋盤,每個格子是黑色或白色。兩個人輪流行動,每次行動可以選擇一個白色的格子以及一個以他為左下角的矩形,並將這矩形的格子顏色翻轉。無法行動者輸,請問先手還是後手必勝?若先手必勝,請輸出必勝的第一步有幾種?字典序最小的解?

T\leq 400, M \leq 100, N \leq 100

可以作為左上角的格子數遞減➡遊戲必定會結束

把每一格想成一個遊戲(i, j)

每個操作都不獨立欸?怎麼辦?

把Xor操作變成加減法


-1

+1

+1

+1

+1

+1

+1

+1

在白色格子裡加一個賽局(賽局合)

加到2➡ 該格特徵值為零

➡跟Xor的結果一樣!

DP出每一格的SGV
O(N*M)種轉移

O(NNMM)

  • 字典序和方法數自己想
  • T到400➡要預處理
namespace solver {
	int n, m;
	const int N = 100, M = 100;
	vector<vector<int>> mp, dp, pre;
	vector<vector<tuple<int, int, int, int>>> v;
	void init_(int _n, int _m) {
		n = _n, m = _m;
		mp.assign(n + 1, vector<int>(m + 1, 0));
	}
	void build() {
		pre.assign(N + 1, vector<int>(M + 1, 0));
		dp.assign(N + 1, vector<int>(M + 1, 0));
		v.assign(2ll * N * M + 1, vector<tuple<int, int, int, int>>());
		rep(i, 1, N) rep(j, 1, M) {
			vector<int> cnt(i * j + 1, 0);
			pre[i][j] = pre[i - 1][j] ^ pre[i][j - 1]
				^ pre[i - 1][j - 1];
			rep(a, 1, i) rep(b, 1, j) {
				int val = pre[i][j] ^ pre[a - 1][j]
					^ pre[i][b - 1] ^ pre[a - 1][b - 1];
				if(val <= i * j) cnt[val] ++;
			}
			rep(a, 0, i * j) if(!cnt[a]) {
				dp[i][j] = a;
				break;
			}
			rep(a, 1, i) rep(b, 1, j) {
				int val = pre[i][j] ^ pre[a - 1][j]
					^ pre[i][b - 1] ^ pre[a - 1][b - 1];
				int to = val ^ dp[i][j];
				v[to].push_back({i, j, a, b});
			}
			pre[i][j] ^= dp[i][j];
		}
	}
	void solve() {
		int ans = 0;
		rep(i, 1, n) rep(j, 1, m) {
			if(mp[i][j]) ans ^= dp[i][j];
		}
		if(!ans) cout << "No\n";
		else {
			tuple<int, int, int, int> best = {INF, INF, INF, INF};
			int cnt = 0;
			for(auto i : v[ans]) {
				int a, b, c, d;
				tie(a, b, c, d) = i;
				if(a > n || b > m) continue;
				if(!mp[a][b]) continue;
				cnt ++;
				best = min(best, {n-a+1, m-b+1, n-c+1, m-d+1});
			}
			int a, b, c, d;
			tie(a, b, c, d) = best;
			cout << cnt << " " << a << " ";
			cout << b << " " << c << " " << d << "\n"; 
		}
	}
	
};
using namespace solver;
signed main() {
	ios::sync_with_stdio(false), cin.tie(0);
	int n, m; build();
	while(cin >> n >> m) {
		init_(n, m);
		rep(i, 1, n) rep(j, 1, m) {
			int x; cin >> x;
			mp[n - i + 1][m - j + 1] = x;
		}
		solve();
	}
	return 0;
}

參考CODE

標準無偏有環賽局

PART FOUR

再探型別

D

N

P

N

P

新型別:D(Draw)平手!

沒有拓樸順序,要怎麼判斷型別阿?

勝負判斷

S(x)=\left\{ \begin{array}{rcl} +1, & & \exist y \in F(x), S(y)=-1\\ -1, & & \forall y \in F(x), S(y) = 1\\ 0, & & otherwise\\ \end{array} \right.

實做就在定義裡...

  • 從確定的點逆推
  • 沒有出度的點→型別為P
  • 可以連到P的點→型別為N
  • 只能連到N的點→型別為P
  • 未定義→型別為D

Wiwi和郝拉在玩遊戲。有一個N個單字的集合S,由Wiwi先說出一個英文單字a,而郝拉要說出S中前三個字元與a的後三個字元相同的單字,依此類推。

eg. purple ➡ please➡ase....

一個單字可以被用多次,不能說出單字的人輸。

N\leq 2\times 10^5, |a_i|\in[3, 8]

當然是Wiwi會贏阿!?

淺談匱乏賽局

PART FIVE

當每堆石頭都是0或1時,

先手必勝若且唯若特徵值是0

觀察

恰有一堆石頭大於二則先手必勝

觀察

超過一堆石頭大於二,

  • 若特徵值非零剩最後一堆超過二的石頭時必輪到先手(N)
  • 若特徵值為零剩最後一堆超過二的石頭時必輪到後手(P)

觀察

  •  每堆石頭數量<2 :特徵值為1則先手必敗
  • 否則特徵值為1則先手必勝

結論

一些題目們

APPENDIX

 

想研究更多的話...

  • ON NUMBERS AND GAMES
  • Game Theory : A Playful Introduction
  • Combinatorial Game Theory
  • 去找劉澈教你怎麼拿到PDF
Made with Slides.com