HDU 2089 不要62 数位dp

题目链接:

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

不要62

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

输入

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

输出

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

样例输入

1 100
0 0

样例输出

80

题解

简单数位dp

#include<map>
#include<set>
#include<cmath>
#include<queue>
#include<stack>
#include<ctime>
#include<vector>
#include<cstdio>
#include<string>
#include<bitset>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=a;i<(b);i++)
#define scf scanf
#define prf printf

typedef long long  LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII;

const int INF=0x3f3f3f3f;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-6;
const double PI = acos(-1.0);

//start----------------------------------------------------------------------

const int maxn=22;

int arr[maxn],tot;
LL dp[maxn][2];
///ismax标记表示前驱是否是边界值
LL dfs(int len,int is6, bool ismax) {
    if (len == 0) {
        ///递归边界,这说明前驱都合法了
        return 1LL;
    }
    if (!ismax&&dp[len][is6]>=0) return dp[len][is6];
    LL res = 0;
    int ed = ismax ? arr[len] : 9;

    ///这里插入递推公式
    for (int i = 0; i <= ed; i++) {
        if(i==4) continue;
        if(i==2&&is6) continue;
        else{
            res += dfs(len - 1, i==6, ismax&&i == ed);
        }

    }
    return ismax ? res : dp[len][is6] = res;
}

LL solve(LL x) {
    tot = 0;
    while (x) {
        arr[++tot] = x % 10;
        x /= 10;
    }
    return dfs(tot, false, true);
}

void init() {
    clr(dp,-1);
}

int main() {
    LL x,y;
    init();
    while(scf("%lld%lld",&x,&y)==2&&x){
        prf("%lld\n",solve(y)-solve(x-1));
    }
    return 0;
}

//end-----------------------------------------------------------------------
posted @ 2016-09-19 15:24  fenicnn  阅读(120)  评论(0编辑  收藏  举报