[每日 C] Strong Password
前言
每天一道的速度比较正常, 但是我想更多的检验一下, 所以今天多做一道, 明天少做也是可以的
难度固定在 \(1400\) 上下即可
思路
直觉认为应该要在原串上做一些操作
显然可以预处理出原串的后缀中有哪些数, 以及这些数最早出现的位置
考虑可行性 \(\rm{dp}\)
令 \(dp_{i, j}\) 表示考虑到密码串的第 \(i\) 位, 当前在原串到了第 \(j\) 位的可能性
特别的地方在于如果和原串没有子序列的关系了, \(j = 0\) , 最终判定答案即为 \(dp_{m, 0}\)
考虑转移
\[\begin{align*}
\begin{cases}
\textrm{case } j \neq 0 :\
dp_{i, j} \stackrel{k \in [l_{i + 1}, r_{i + 1}]}{\longrightarrow}
\begin{cases}
\textrm{case } \exists k \in S[i : n] : dp_{i + 1, pos_k} \\
\textrm{otherwise } : dp_{i + 1, 0}
\end{cases} \\
\textrm{otherwise } :
dp_{i, 0} \stackrel{k \in [l_{i + 1}, r_{i + 1}]}{\longrightarrow}
dp_{i + 1, 0}
\end{cases}
\end{align*}
\]
复杂度是 \(\mathcal{O} (\sum nm)\) 的
总结
子序列问题, 常常在原串的基础上做 \(\rm{dp}\)

浙公网安备 33010602011771号