不要62(數位dp)

傳送門

描述

杭州人稱那些傻乎乎粘嗒嗒的人爲 62(音:laoer)。

杭州交通管理局經常會擴充一些的士車牌照,新近出來一個好消息,以後上牌照,不再含有不吉利的數字了,這樣一來,就可以消除個別的士司機和乘客的心理障礙,更安全地服務大衆。

不吉利的數字爲所有含有 4 或 62 的號碼。例如:62315,73418,88914 都屬於不吉利號碼。但是,61152 雖然含有 6 和 2,但不是 連號,所以不屬於不吉利數字之列。

你的任務是,對於每次給出的一個牌照號區間 [n,m],推斷出交管局今後又要實際上給多少輛新的士車上牌照了。

輸入格式

輸入包含多組測試數據,每組數據佔一行。

每組數據包含一個整數對 n 和 m。

當輸入一行爲“0 0”時,表示輸入結束。

輸出格式

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

數據範圍

1≤n≤m≤107

輸入樣例:

1 100
0 0

輸出樣例:

80

這題是經典的數位dp,對於包含4和62就是壞的數字

我們首先計算數字的位數和每一位上的數存起來,因爲我們需要控制上限

然後通過深搜來遍歷每一位,然後搜索的時候記憶化一下

AC代碼如下:
#include <stdio.h>
#include <string.h>
#include <algorithm>
using namespace std;
int dp[8][2],digit[8];   //dp[i][state]表示當前是第i位數字,state表示前面一位是否爲6
int dfs(int len,bool state,bool up) {         //len表示我們當前的長度,state表示上一位是否爲6,up表示上一位是否達到上限
	if(!len)	return 1;
	if(!up&&dp[len][state]!=-1)	return dp[len][state];
	int ret=0,upmax=up?digit[len]:9;       //如果上一位到達上限,則這一位上限是digit[len],否則爲9
	for(int i=0;i<=upmax;i++){
		if(i==4||state&&i==2)	continue;
		ret+=dfs(len-1,i==6,up&&i==upmax);
	}
	if(!up)	dp[len][state]=ret;           //上一位沒達到上限表示這個結果是可以通用的,
	return ret;
}
int f(int n) {
	int len = 0;
	while(n) {
		digit[++len] = n % 10;
		n /= 10;
	}
	return dfs(len,false,true);
}
int main() {
	int a,b;
	memset(dp,-1,sizeof(dp));
	while(scanf("%d%d",&a,&b),a||b) {
		printf("%d\n",f(b)-f(a-1));
	}
	return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章