hdu2089 不要62 数位dp

题目:

http://acm.hdu.edu.cn/showproblem.php?pid=2089

题意:

Problem Description
杭州人称那些傻乎乎粘嗒嗒的人为62(音:laoer)。
杭州交通管理局经常会扩充一些的士车牌照,新近出来一个好消息,以后上牌照,不再含有不吉利的数字了,这样一来,就可以消除个别的士司机和乘客的心理障碍,更安全地服务大众。
不吉利的数字为所有含有4或62的号码。例如:
62315 73418 88914
都属于不吉利号码。但是,61152虽然含有6和2,但不是62连号,所以不属于不吉利数字之列。
你的任务是,对于每次给出的一个牌照区间号,推断出交管局今次又要实际上给多少辆新的士车上牌照了。

Input
输入的都是整数对n、m(0< n≤m<1000000),如果遇到都是0的整数对,则输入结束。

Output
对于每个整数对,输出一个不含有不吉利数字的统计个数,该数值占一行位置。

思路:

数位dp简单题,直接预处理打表也可以的

#include <bits/stdc++.h>

using namespace std;

const int N = 20 + 10;

int dp[N][2];
int dig[N];

int dfs(int pos, bool status, bool limit)
{//pos代表位置,status代表上一个数字是不是6,limit代表当前位置取值有没有限制
    if(pos < 1) return 1;
    if(! limit && dp[pos][status] != -1) return dp[pos][status];
    int en = limit ? dig[pos] : 9;
    int ans = 0;
    for(int i = 0; i <= en; i++)
        if(status && i == 2) ans += 0;
        else if(i == 4) ans += 0;
        else ans += dfs(pos-1, i == 6, limit && i == en);
    if(! limit) dp[pos][status] = ans;
    return ans;
}
int work(int n)
{
    int tn = n, k = 0;
    while(tn) dig[++k] = tn % 10, tn /= 10;
    memset(dp, -1, sizeof dp);
    return dfs(k, 0, 1);
}
int main()
{
    int n, m;
    while(scanf("%d%d", &n, &m), n || m)
        printf("%d
", work(m) - work(n-1));
    return 0;
}