数位 DP 练习笔记

P1836 数页码

不想写数位 DP 的可以参考该做法。

枚举数字 \(x=0\sim 9\),考虑其在第 \(i\) 位上的贡献。将 \(n\) 拆成当前位左边部分 \(a\)、当前位 \(b\)、当前位右边部分 \(c\)。分类讨论:

  • \(x<b\)\(0\sim a\)\(10^{i-1}\) 的贡献;
  • \(x=b\)\(0\sim a-1\)\(10^{i-1}\) 的贡献,\(a\)\(c+1\) 的贡献;
  • \(x>b\)\(0\sim a-1\)\(10^{i-1}\) 的贡献。

特殊地,因为不能有前导零,所以当 \(x=0\)\(10^{i-1}\) 的贡献会少一次,但不用判因为 \(x=0\) 相当于没有贡献……

P1590 失踪的 7

这么简洁的题目当然不用数位 DP 啦。

\(n\) 搞成 \(10\) 的幂次之和计算。比如说 \(1234\) 就拆成 \(1\sim 4,1\sim 30,1\sim 200,1\sim 1000\) 来计算。枚举后缀长度 \(i\),除去最高位外的每一位都可以填除 \(7\) 以外的任何数字,所以它的贡献为 \(9^{i-1}\) 再乘上最高位能填的数字(不为 \(7\) 且小于最高位的数字)。

不过这样处理本质是把所有数减 \(1\) 然后从 \(0\) 开始计数,当最高位数字为 \(1\) 时会多算一次,要减掉。

虽然题目保证了 \(n\) 本身不包含数字 \(7\),但这个做法可以轻松地拓展到对 \(n\) 没有限制的情况:如果除去当前枚举的后缀外前面还有 \(7\),直接把当前后缀的贡献记为 \(0\)

posted @ 2025-05-13 18:18  Sumering  阅读(40)  评论(0)    收藏  举报