數位dp hdu2089

杭州人稱那些傻乎乎粘嗒嗒的人爲62(音:laoer)。 
杭州交通管理局經常會擴充一些的士車牌照,新近出來一個好消息,以後上牌照,不再含有不吉利的數字了,這樣一來,就可以消除個別的士司機和乘客的心理障礙,更安全地服務大衆。 
不吉利的數字爲所有含有4或62的號碼。例如: 
62315 73418 88914 
都屬於不吉利號碼。但是,61152雖然含有6和2,但不是62連號,所以不屬於不吉利數字之列。 
你的任務是,對於每次給出的一個牌照區間號,推斷出交管局今次又要實際上給多少輛新的士車上牌照了。 

Input

輸入的都是整數對n、m(0<n≤m<1000000),如果遇到都是0的整數對,則輸入結束。 

Output

對於每個整數對,輸出一個不含有不吉利數字的統計個數,該數值佔一行位置。 

Sample Input

1 100
0 0

Sample Output

80

第一道數位dp,花了一下午看終於有點眉目了。

給出兩位大佬的博客。第一篇      第二篇

以下是自己對數位dp的理解:

其實說是數位dp,個人感覺就是個字符串的處理。但是由於是數字,所以他有特殊的性質就是他的遍歷只有0~9,並且可以比較大小。

數位dp第一步要做的就是把一個整數的各個位數分出來,接下來要做的就是dfs的過程。

例如:按照數位的方法遍歷 0~231   第一位的選擇只有0,1,2。當第一位爲0或1時,第二位和第三位都可以取到0~9的值。

當取到2時,第二位的選擇就是0,1,2,3,同理當第二位的選擇不爲3時,個位的選擇就是0~9.

我們先看道題目 hdu2089

題意就是讓我們找出 a~b之間的 不包含‘4’和連續的‘62’的數字有多少個。

#include <queue>
#include <cstdio>
#include <set>
#include <string>
#include <stack>
#include <cmath>
#include <climits>
#include <map>
#include <cstdlib>
#include <iostream>
#include <vector>
#include <algorithm>
#include <cstring>
#include <stdio.h>
#include <ctype.h>
#include <bitset>
#define  LL long long
#define  ULL unsigned long long
#define mod 10007
#define INF 0x7ffffff
#define mem(a,b) memset(a,b,sizeof(a))
#define MODD(a,b) (((a%b)+b)%b)
using namespace std;
const int maxn = 100010;
int n,m,cnt;
int a[20];
LL dfs(int pos,int pre,bool limit)//當前遍歷的位數,前一個的數字,是否有上限值
{
    if(pos == -1) return 1;
    LL ans = 0;
    int up = limit ? a[pos] : 9;//若limit爲真,可以遍歷的上限就是(0~當前的數字),反之就是0~9
    for(int i = 0; i <= up; i++){
      if(i == 4) continue;
      if(pre == 6 && i == 2) continue;排除4和62的情況
      ans += dfs(pos - 1,i,limit && i == a[pos]);//遍歷下一位,當前位作爲下一位傳入,limit情況。只要當limit爲一次假時,以後都爲假。
    }
    return ans;
}
LL solve(LL x)//分離位數
{
    int cnt = 0;
    while(x){
      a[cnt++] = x % 10;
      x /= 10;
    }
    return dfs(cnt - 1,-1,true);
}
int main()
{
    LL x,y;
    while(~scanf("%lld%lld",&x,&y) && (x + y)){

        printf("%lld\n",solve(y) - solve(x - 1));//0~(a - 1),0~b算出來後 相減得出a~b

    }

    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章