数位dp问题一般是求某个区间[l, r]中满足某些条件的数的个数,通常情况下,l和r取值可能很大(2 ^ 31 - 1),而只需要解决以下两个问题就可以得出答案:
1、把求区间[l, r]满足条件的数用前缀和转为求[0 ~ r] - [0 ~ l - 1]
2、采用“分类讨论”的方法来变相“枚举”[0 ~ n]的所有数字,拆分n=abcd…,则第一位取值有2中情况,其余同理:
(1)0~a - 1
(2)a
当取值为0~a - 1这种情况时,通常可以通过“预处理”来解决,预处理采用dp递推而来,一般来说,数位dp难点就是如何正确高效进行预处理,一般定义f[i][j]含义为“i位数,最高为j时…”
模板
l, r = map(int, input().split())#输入区间
f = [n][n]#数组f用来保存预处理的值
#1、处理f的边界条件
pass
#2、确定f
for i in range(2, n):#位数
for j in range():#枚举每一位的数字
#递推式
print(dp(r) - dp(l - 1))#利用前缀和解决
dp函数模板 def dp(n)
if not n:return 0/1/...#特判
#获取n的每一位
g = []
while n:
g.append(n % 10)
n //= 10
ans, last = 0, None#ans表示答案,last表示在循环过程中需要传递的数据
for i in range(len(g) - 1, -1, -1):#从高到低枚举
x = g[i]
for j in range(x):#枚举这位上可能的数字
#判断该左子树是否存在
pass
ans += #具体逻辑处理代码
#判断右子树是否存在
pass
#更新last
pass
#特判
if not i and ...: ans += 1
#对于前导0的特殊处理代码
pass
return ans
建议你去看力扣上面灵茶山艾府的数位 DP 模板