做题小计 arc170c
*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!状态设计和删去都非常巧妙!