11.19 CW 模擬賽 T3.又見 LIS

Yorg發表於2024-11-20

前言

老登你也知道你又在出 \(\rm{LIS}\)

演算法

首先我們需要注意到, 本質上和隨機了一個 \(1 \sim n\) 的排列沒有任何區別
具體的, 任意一個 \(\rm{LIS}\) 數列, 都僅僅是由大小關係推過來的, 並且可以證明, \(\rm{LIS}\) 數列相同, 當且僅當大小關係完全相同

注意到這個之後(事實上我注意不到) , 我們可以拿到暴力的 \(20\%\)

先考慮全是 \(0\) 的情況
注意到 \(\rm{LIS}\) 的數列, 必須滿足

\[a_1 = 1, a_i \leq \mathop{ \rm{max} }\limits_{j < i} (a_j + 1), a_i \geq 1 \]

\(dp_{i, j}\) 表示考慮了前 \(i\) 位, 其中 \(\mathop{ \rm{max} }\limits_{k < i} (a_k) = j\) 時可能性數量
轉移是顯然的 (注意最大值一次只能變化 \(1\))

\[dp_{i, j} = j dp_{i - 1, j} + dp_{i - 1, j - 1} \]

考慮 \(a_i\) 被指定的情況
有,

\[dp_{i, j} = dp_{i - 1, j} , j > a_i \]

\[dp_{i, a_i} = dp_{i - 1, a_i - 1} + dp_{i - 1, a_i} \]

現在我們需要考慮 \(a_i = -1\) 的情況
由於這一位不受關注, 我們直接填上最大的可能, 即

\[dp_{i, j} = dp_{i - 1, j - 1} \]

具體的, 只要填上最大的數, 後面所有的可能都可以被考慮到

時間複雜度 \(\mathcal{O}(n ^ 2)\)

程式碼

總結

一般來說, 可以將約束條件加入 \(\rm{dp}\) 柿子方便遞推

這個題中, 關鍵資訊是 : 最大值一次變化量最大為 \(1\)

積累一下, 思路確實非常好, 善於利用 \(\rm{Subtask}\) 推到正解

還是需要多聯絡 \(\rm{dp}\)