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

posted @ 2024-03-11 20:58  g1ove  阅读(6)  评论(0编辑  收藏  举报