1. 程式人生 > 其它 >CF919F A Game With Numbers 題解

CF919F A Game With Numbers 題解

你谷 link

CF link

這裡帶來一個跑得很快而且寫起來也相對簡單的做法。

首先考慮這種題一看就是博弈論,主要就是一個性質——能走到必敗態的都是必勝態,能走到必勝態的才是必敗態。

那麼就很顯然了,從終止狀態反向推,先看看狀態數,一個人的手牌只有八張五種,所以最多隻有 \(495\) 種狀態,那麼兩個人的手牌加起來也不過只有約 \(2.5\times10^5\) 種狀態。

考慮先將這些狀態編上號,建立雙射,方便之後的轉移,然後考慮做轉移,設 \(f_{i,j}\) 表示先手的狀態編號為 \(i\),後手狀態編號為 \(j\) 的態勢。

考慮怎麼轉移,首先初始狀態,假設手牌全是 \(0\) 的狀態編號為 \(0\)

,則 \(f_{0,i}=1\)\(f_{i,0}=0\),且 \(f_{i,0}\) 可以作為狀態轉移別人,而 \(f_{0,i}\) 不行,因為我們是反向轉移,所以當前的先手如果已經贏了的話,上一步後手就根本無法操作。

現在考慮如何轉移,一個點肯定是倒推上一個狀態,所以肯定是當前後手的一個數減去當前先手的一個非零數得到上個狀態的原數,如果該狀態是必敗態,則轉移的就是必勝態,如果該狀態是必勝態,則轉移到必敗態,但是不是一定轉移,而是隻有確定這個點正向能轉移到的點都是必勝態,這個點才是必敗態。

一個點能轉移多少點呢?考慮手裡任意一非零牌跟對手的每非零牌都可以匹配進行操作,所以就可以快速得到轉移種類,注意這裡一模一樣的牌就算有多張,匹配轉移也只能算一種。

最後查詢就直接呼叫查詢就好了,程式碼比較簡單。