P4124 [CQOI2016]手机号码 题解
看起来就很像是一道数位dp,\(L\) 和 \(R\) 很大,并且限制和大小没关系。考虑状态的设计:剩余长度 \(len\),是否有上限限制 \(lim\),这两个肯定是必须的。因为要统计连续三个位置相同,所以要记录 \(pre1,pre2\) 表示前两位是什么数(当然也可以记录上一位和它们两个是不是相等)。还有一个关于 \(4\) 和 \(8\) 的限制,考虑用 \(0/1/2\) 分别表示还没有选 \(4\) 和 \(8\)/选了 \(4\)/选了 \(8\)。
这样的话,还是不能记忆化,因为到这一位如果前面已经有过连续三个相同,后面就不需要有了,否则后面必须得有。这两种情况答案不相同,所以可以再开一维表示前面有没有连续三个相同。这样就设出了所有的状态:
dfs(len,lim,pre1,pre2,have,flag)
,have就表示选 \(4,8\) 的三种状态,flag就表示前面有没有满足连续的条件。记忆化就是 f[len][pre1][pre2][have][flag]
,lim不要放进来。这样总的复杂度是状态数乘上转移的复杂度,是 \(O(10\times 10\times 10\times 10\times 3\times 2)=O(60000)\),完全可以通过。
这道题目算是比较经典、也比较困难的数位dp题了,通过这个题可以更深刻地通过状态设计去体会消除dp后效性的过程。