DP 系列(七·完结篇):数位 DP

本讲定位:处理这样一类统计题——“$[L, R]$ 里有多少个数,它的数位满足某条件”(不含 62、相邻数位差至少 2、数位和是 7 的倍数……)。$R$ 大到 $10^{18}$,逐个枚举想都别想;但一个数再大也只有不到 20 位——按”位”做文章,逐位填数,就是数位 DP。它也是全系列”状态里只留未来需要的信息”这句心法最纯粹的展示。

前置知识:专题一(记忆化搜索——本讲的主力写法,务必先熟);专题六第 7 节末尾”只留未来需要的信息”的讨论。

标注 ⭐ 的小节为进阶内容。本讲是系列最后一讲,文末有七讲总回顾与后续学习地图。


1. 数位 DP 长什么样

先认题型。下面这些问法都是数位 DP:

共同点:区间统计 + 条件长在数位上。数值本身多大不重要,重要的是它”写出来”的样子。

第一步永远是前缀相减。 区间 $[L, R]$ 不好直接做,但记 $(n) = $ “$[1, n]$ 中满足条件的数的个数”,则

$$ \operatorname{ans}(L, R) = \operatorname{count}(R) - \operatorname{count}(L - 1) $$

这一步把双边界问题砍成单边界——和前缀和的思想一模一样。此后我们只讨论”$\le n$“怎么数。


2. 核心框架:逐位填数 + 记忆化

把 $\le n$ 的数想象成从最高位到最低位逐位填数字填出来的。比如 $n = 2586$,填第一位时:

这揭示了整个框架的核心结构:搜索树上,每一层最多只有一个结点是”贴上界”的(一路顶格填下来的那个),其余全是”自由”的。而两棵自由子树,只要剩余位数相同、且已填前缀在”条件”上等价,它们就长得一模一样——这正是重叠子问题,记忆化伺候。

再加一个细节:我们按固定位数填数,但 $58$ 在 $4$ 位框架里是 $0058$——开头的 $0$ 是前导零,不是真正的数位。有些条件(比如”相邻数位差 $\ge 2$“)对前导零不适用,所以还要一个标记 lead 表示”是否还没填过真正的数字”。