問題:給定 $n\in[2,100]$ 個頂點以及 m 條從 v 到 u 並且標有一個英文小寫字母 c 的有向邊,每條邊都不會指向自己,每對頂點之間至多只會有一條邊,整張圖也不會有環。定義遊戲規則如下:每次先手後手會各自站在一個頂點上 (可以重疊),先手必須選一條邊走到下一個頂點,假設這條邊的字母是 c,那麼此時後手變先手,他/她也要繼續選一條邊走到下一個頂點,但是這條邊的字母就必須不小於 c,遊戲進行到最後沒路走的人就輸了。請問當先手跟後手的起始點分別散佈在不同頂點的時候誰會贏?
解法:這題也是典型的遊戲理論,它有趣的地方在於 state 的設計,官方解答給的定義是 dfs(u, v, c) 代表先手站在 u、後手站在 v,此時可行邊的字母必須不小於 c 的時候,如果先手會贏則為 true,後手會贏則為 false。吾人易知它的遞迴算法為:如果存在一條標有字母 c' $\ge$ c 的邊 u $\rightarrow$ u$_0$ 使得 dfs(v, u$_0$, c') 是為 false,這意味著先手可以選擇這條邊讓後手必敗,使得 dfs(u, v, c) 是為 true;反之如果不存在這樣子的一條邊,那 dfs(u, v, c) 就只能是 false 了。除了遞迴函式的寫法之外,DP 的設計也很巧妙,這題還有一個很重要的特性是,若 dfs(u, v, c) 是 true,那麼所有對於 c' $\le$ c 的 dfs(u, v, c') 也勢必是為 true;如果 dfs(u, v, c) 是 false,那麼所有對於 c' $\ge$ c 的 dfs(u, v, c') 也勢必是為 false,所以我 dp[u][v][c] 的第三個 entry 其實用不到 26 個字元,只要維護兩個數字分別是結果為 true 的上界和結果為 false 的下界即可。