数位类计数

问题:

竞赛中存在这样一种计数类问题:求在[a,b]区间内满足条件x的数个数(或其他类似目的)

这种问题统称为数位类计数问题,可以用数位DP解决。

解析:

首先这种问题一般满足区间减法,所以我们可以把它转化为 [0,b]的个数 - [0,a)的个数。

然后问题变成了:求在[0,b]区间内满足条件x的数个数。

不难发现一个个枚举通常会超时,而且数的个数明显有一定规律可循。

所以我们可以用加法原理,把它分解为若干个子问题求解,具体分解方法见《训练指南》上这张图,完美地说明了一切。

我们把一段区间分解为若干个带有“前缀”的“模板”和一个比原问题规模小的问题,对于带“*”的模板,不难发现所有模板的状态不变。

因此我们有了这样一个思路:

设F[i][j]为以 j 开头的 i位数中满足条件的个数,用递推可以在约线性时间内求出整个F数组,然后在不同子问题中在O(1)时间内求解。

但注意这里的i位数是否允许前导零。更多时候,对于以“0”开头的数,前导零是非法的。

步骤:

  1. 用递推求出F数组
  2. 计算前导零非法时的个数
  3. 分解问题,用DP求解
posted @ 2016-05-16 19:17  Krew  阅读(123)  评论(0)    收藏  举报