*2000 *dp
arc170c
我覺得很妙的 dp 題目。
Solution
一眼下去,似乎所有 \(1\) 的位置是固定的,其餘位置隨便填,答案就是 \(m^{count(1)}\) ?
這一步在 \(m\ge n\) 的時候是對的。
但是 \(m< n\) 的情況很不好搞。
序列問題容易想到 dp 。看題目,考慮要記錄什麼值。發現 \(mex\) 很難搞,要搞的話似乎要搞個狀壓,把所有狀態記錄下來,這樣不就爆了嗎。顯然不行。
根據通用的套路,我們發現,對於所有數字 \(x\) ,似乎只有它第一次出現是對 \(mex\) 有貢獻的?
換種思考方式,我們令 \(f_{i,j,k}\) 表示在時刻 \(i\) 時,數字 \(j\) 已經被取了。\(k=1\) 表示 \(1\to j\) 已經全部被取了。
我們發現這真的很不好搞。轉移就已經很難搞了。
考慮 \(mex\) 在 \(f\) 陣列中最根本的意義。不就是強制取最左邊未被取的一位?
這時候我們定義新狀態 \(f_{i,j,k}\) 表示時刻 \(i\) ,取了 \(j\) 個數,保證取了前 \(k\) 個。
如果 \(s_i=1\) 那麼 \(f_{i,j,k}=f_{i-1,j-1,k-1}\)
否則分類討論,情況 \(1\) 就是重複取數,情況 \(2\) 就是取新數。
\(f_{i,j,k}=f_{i-1,j,1\to k}\times j + f_{i-1,j-1,1\to k}\times (m-j)\)
推出來式子後我們發現 \(k\) 屁用沒有,直接給這一位刪去,定義新狀態 \(f_{i,j}=\sum\limits_{k=1}^nf_{i,j,k}\)存舊狀態。
這時候我們發現轉移是一樣的,而且不用列舉 \(k\) 。
時間複雜度 \(O(n^2)\) 。
很妙的題!tql!狀態設計和刪去都非常巧妙!