给定表示书的总页码的10进制整数n(1≤n≤109)。编程计算书的全部页码中分推荐别用到多少次数字0,1,2,…,9。
时间: 2023-06-12 19:04:56 浏览: 153
这个问题可以使用数位DP(数字动态规划)来解决。我们可以定义一个状态 $f[i][j]$ 表示在 $i$ 位数字中,数字 $j$ 出现的次数。那么最终的答案就是 $f[n][0], f[n][1], ..., f[n][9]$ 中所有数字的和。
接下来我们考虑如何转移。假设我们已经求出了 $f[i-1][0], f[i-1][1], ..., f[i-1][9]$,现在要求出 $f[i][0], f[i][1], ..., f[i][9]$。我们可以枚举第 $i$ 位数字 $d$($0\leq d\leq 9$),然后根据 $d$ 是否为 $0$ 分情况讨论:
- 如果 $d$ 不为 $0$,那么 $f[i][d]=f[i-1][0]+f[i-1][1]+\cdots+f[i-1][9]$,因为所有 $i-1$ 位数字的末尾都可以加上 $d$,所以 $d$ 出现的次数就是 $f[i-1][0]+f[i-1][1]+\cdots+f[i-1][9]$。
- 如果 $d$ 为 $0$,那么 $f[i][d]=f[i-1][0]+f[i-1][1]+\cdots+f[i-1][9]-f[i][0]$。这个转移比较巧妙,因为如果在 $i$ 位数字上放 $0$,那么在 $i-1$ 位数字上放任何数字都可以得到一个以 $0$ 结尾的数字,所以 $0$ 出现的次数就是在 $i-1$ 位数字上出现的次数。但是我们要注意到,如果我们在 $i-1$ 位数字上放 $0$,那么在 $i$ 位数字上放 $0$ 就会出现两个 $0$,这是不合法的,所以需要减去 $f[i][0]$。
最终的时间复杂度为 $O(\log n)$。下面是 Python 代码:
阅读全文