数位DP与模板题

数位DP与模板题

数位dp是一种计数用的dp,一般就是要统计一个区间[le,ri]内满足一些条件数的个数。所谓数位dp,字面意思就是在数位上进行dp咯。数位还算是比较好听的名字,数位的含义:一个数有个位、十位、百位、千位……数的每一位就是数位啦!

模板题

HDOJ2089 不要62
给出一个数字范围,求范围内不出现62和4的数字的数量

#include<cstdio>
#include<cstring>
int num[10];
int dp[10][2];
int dfs(int pos, int state, int limit)
{
    if (pos == -1)    return 1;  //枚举到最后一位,该数字合法
    if (!limit && dp[pos][state] != -1)        return dp[pos][state];  //记忆化搜索,之前已经搜到了没有限制的答案,那么就直接返回
    int up = limit ? num[pos] : 9;   //是否有限制
    int tmp = 0;
    for (int i = 0; i <= up; i++)
    {
        if (i == 4)    continue;
        if (state == 1 && i == 2)    continue;   //state记录的是上一位的状态
        tmp += dfs(pos - 1, i == 6, limit && i == num[pos]);
    }
    if (!limit)    dp[pos][state] = tmp;
    return tmp;
}
/*把数字每一位存入数组,进行记忆化搜索*/
int solve(int x)
{
    int pos = 0;
    while (x)
    {
        num[pos++] = x % 10;
        x /= 10;
    }
    return dfs(pos - 1, 0, 1);
}

int main()
{
    int n, m;
    while (scanf("%d%d", &n, &m) != EOF && (n || m))
    {
        memset(dp, -1, sizeof(dp));
        printf("%d\n", solve(m) - solve(n - 1));
    }
    return 0;
}

具体分析留坑

... ... ...