求助:基于动态规划实现区间[a,b]内满足双条件数的高效查找
这题确实是**数位动态规划(Digit DP)**的经典应用场景——暴力枚举1e11级别的数完全不现实,我给你拆解下具体的解决思路,分情况处理效率会高很多:
核心思路
数位DP的核心是先计算[0, x]范围内满足条件的数的数量,然后通过f(b) - f(a-1)得到[a,b]的结果,把区间问题拆解成两个端点的计算问题。不过因为k的范围可以到1e11,直接用常规DP会有状态爆炸的问题,所以得分情况处理:
1. 先处理k过大的边界情况
当k大到区间里最多只有1个k的倍数时,直接枚举检查比DP快得多:
- 如果
k > b:- 只有当
a ≤ k ≤ b时,k本身是候选数,计算它的各位数字之和,看是否在[c,d]范围内,符合就输出,否则没有结果。 - 其他情况直接输出空结果。
- 只有当
- 如果
k > (b - a + 1):- 先算出区间里第一个k的倍数:
x = ((a + k - 1) // k) * k - 要是
x ≤ b,就检查x的各位和是否在[c,d],符合就输出x,否则没有结果。
- 先算出区间里第一个k的倍数:
2. 数位DP实现(针对k较小的情况)
当k小到区间里有多个k的倍数时,就用记忆化搜索版的数位DP来计算。我们定义一个递归函数,跟踪几个关键状态:
状态参数说明
我把每个参数的作用用大白话解释下:
pos:当前处理到第几位(从高位往低位算,比如1e11是11位数,pos从0到10)mod:当前选的数字组成的数对k取余的结果(范围0到k-1,用来判断最终是否能被k整除)sum_digits:当前选的数字的各位之和(范围0到99,刚好对应题目里c和d的上限)tight:布尔值,标记当前是否被原数的数位限制(比如原数是1234,前两位选了12的话,第三位最多只能选3,不然就超过原数了)leading_zero:布尔值,标记是否还在写前导零(比如前面几位都是0,此时各位和还是0,直到选第一个非零数字)
递归逻辑
- 终止条件:当所有数位处理完(
pos == 总位数):- 如果还是前导零状态(也就是数字是0),题目里a≥1,所以不算,返回0。
- 否则检查两个条件:
mod == 0(能被k整除)且c ≤ sum_digits ≤ d(各位和在范围内),符合就返回1,否则返回0。
- 记忆化缓存:如果当前状态之前算过,直接返回缓存的结果(避免重复计算)。
- 确定当前位的可选数字范围:
- 如果
tight是True,当前位最大只能选原数对应位的数字;否则可以选0到9。
- 如果
- 遍历所有可能的数字:
- 对每个可能的数字
digit,计算新的状态:new_tight:如果之前是tight状态,且当前选的数字等于原数对应位,那新状态还是tight,否则不是。new_leading_zero:如果之前是前导零,且当前选的还是0,那依然是前导零,否则不是。new_sum:如果还是前导零,各位和保持0;否则加上当前digit。new_mod:如果还是前导零,余数保持0;否则用(mod * 10 + digit) % k计算新余数(这样每次都取模,不会出现大数溢出)。
- 把所有可能的digit对应的结果加起来,就是当前状态的总数量。
- 对每个可能的数字
- 缓存并返回结果:把当前状态的结果存起来,返回给上一层。
实现细节提醒
- 转数位数组:把要计算的数字(比如b或者a-1)转成高位在前的数组,方便逐位处理。
- 处理a=1的情况:计算
f(a-1)就是计算f(0),此时要注意0不在[a,b]里,所以结果应该是0。 - 语言选择:Python的整数没有溢出问题,用
lru_cache做记忆化很方便;如果用C++这类语言,要注意用64位整数(long long)处理模运算,避免溢出。 - 状态优化:前导零状态其实可以和sum_digits合并(前导零时sum_digits一定是0),能少一个状态维度,节省内存和计算时间。
3. 组合最终结果
计算出f(b)([0,b]中符合条件的数的数量)和f(a-1)([0,a-1]中符合条件的数的数量),两者的差就是[a,b]的结果。如果需要列出所有符合条件的数,那在DP过程中要记录符合条件的数字字符串,最后整理输出就行,思路和计数是一致的。
实用小建议
- 优先处理大k情况:k越大,区间内的k倍数越少,直接枚举比DP快太多,别上来就写DP。
- 先测小案例:先写暴力代码测试小范围的情况(比如a=1,b=100,k=5,c=3,d=10),验证DP的结果是否正确,避免逻辑错误。
- 调整k的阈值:根据你用的语言和硬件性能,调整什么时候用DP、什么时候直接枚举,比如在Python里,k超过1e5的时候,直接枚举可能比DP更快。
内容的提问来源于stack exchange,提问作者bordus
相关产品推荐
相关产品推荐

