动态规划 · HTML
数学 / 逻辑形态
solve(pos,tight,started,summary) 返回从当前位置填完的方案数。digit 范围 0..limit,其中 limit=tight?digits[pos]:base-1;next_tight=tight and digit==limit_digit。区间 [L,R] 用 F(R)-F(L-1)。
识别信号
- 要求统计 [0,N] 或 [L,R] 内整数。
- 性质可逐位更新,如数位和、余数、出现次数或相邻约束。
- N 很大,逐数枚举不可行。
- 大量数共享相同高位前缀状态。
- 上界限制可由 tight 标志表达。
容易误判的相似信号
| Signal | Why it is different |
|---|
| 只需计算一个给定数的数位性质 | 直接循环拆位即可,不需 DP。 |
| 性质依赖完整任意历史 | 若无法压缩成小 summary,状态会爆炸。 |
| 无上界且长度很短 | 普通组合计数或矩阵递推可能更直接。 |
核心不变量
memo 状态代表所有具有同一 pos/tight/started/summary 的前缀,它们的合法后缀集合完全相同;tight 准确记录是否仍贴住上界前缀。
状态、转移与处理顺序
| Item | Definition |
|---|
| State | pos、tight、started,以及性质所需 summary(余数、和、计数、上一位等)。 |
| Transition | 枚举当前合法 digit,更新 started/summary;只有当前仍 tight 且 digit 等于上界位时保持 tight。 |
| Frontier / order | 从最高位向最低位的 DFS/迭代层;常只 memo tight=False 状态或将 tight 纳入缓存。 |
Python 骨架
from functools import lru_cache
def count_digit_sum_at_most(n, target):
if n < 0: return 0
digits = list(map(int, str(n)))
@lru_cache(None)
def dfs(pos, tight, total):
if total > target: return 0
if pos == len(digits): return int(total == target)
limit = digits[pos] if tight else 9
ans = 0
for d in range(limit + 1):
ans += dfs(pos + 1, tight and d == limit, total + d)
return ans
return dfs(0, True, 0)
正确性思路
- 每个 0..N 的定长补零表示对应唯一数位选择路径。
- tight 规则恰好排除首个超过上界的前缀,保留所有不超过上界的路径。
- summary 按位更新且终点只接受目标性质;互异路径对应互异整数,计数无重漏。
复杂度
| Time | Space | Parameters |
|---|
| O(D·B·|Summary|·2),常数依转移 | O(D·|Summary|·2) | D 为位数,B 为进制,Summary 为统计状态规模。 |
边界条件
- n<0 用于 L-1
- 数字 0 是否计入
- 前导零与 started
- 上界本身
- summary 剪枝
- 不同进制
错误模式
| Pattern | Why it fails / fix |
|---|
| next_tight 比较错对象 | 必须是 tight and ddigits[pos],不是 dlimit 在所有语境下随意写。 |
| 前导零当真实数位 | 统计出现次数/相邻性质时需 started 区分未开始前缀。 |
| 区间减法漏 L=0 | 定义 F(n<0)=0,统一 F(R)-F(L-1)。 |
| 缓存包含可变外部状态 | 影响后缀的量都必须进入 key;与上界相关的 digits 应固定在一次调用内。 |
选择与排除规则
- 先把区间查询化为前缀计数 F(N)。
- 证明性质能由小 summary 逐位更新。
- 明确前导零是否属于数字表示。
- 用 brute force 小 N 对拍边界。
相关模板
| Relation | Template | Boundary |
|---|
| state-feature | 模运算与快速幂 | summary 维护当前数值模 m。 |
| composition | 有限状态机 DP | summary 是由上一数位驱动的有限自动机状态。 |
原创微型例子
| 环节 | 内容 |
|---|
| Result | 计数为 3,22 通过 tight 边界保留。 |
| Setup | 统计 0..25 中数位和为 4 的整数。 |
| Trace | 合法路径对应 4、13、22;前缀 2 tight 时末位最多 5。 |
Recall prompts
我的补充