HDU2089《不要62》

ProjectDP - 26

数位DP板子题

Problem Description

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

Input

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

Output

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

Sample Input

1
2
1 100
0 0

Sample Output

1
80

Author

qianneng

解析

不会讲啊QAQ

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//
// 26.cpp
// ProjectDP
//
// Created by HandwerSTD on 2019/1/28.
// Copyright © 2019 Handwer STD. All rights reserved.
//

#include <iostream>

#define FILE_IN(__fname) freopen(__fname, "r", stdin)
#define FILE_OUT(__fname) freopen(__fname, "w", stdout)
#define IMPROVE_IO() std::ios::sync_with_stdio(false)

using std::cin;
using std::cout;
using std::endl;

const int MAXLENGTH = 8 + 4;

/*
*
* dp[i][j]: length = i, the start number = j
*
*/

int dp[MAXLENGTH][MAXLENGTH];
int n, m;

void Init() {
dp[0][0] = 1;
for (int i = 1; i <= 9; ++i) {
// enumeration length
for (int j = 0; j <= 9; ++j) {
if (j == 4) dp[i][j] = 0;
else {
for (int k = 0; k <= 9; ++k) {
dp[i][j] += dp[i - 1][k];
}
if (j == 6) dp[i][j] -= dp[i - 1][2];
}
}
}
}

int Solve(int x) {
// returns the amount in [0, x)
int ans = 0;
int num[MAXLENGTH] = {0};
// num[0] <=> cnt
while (x) {
num[++num[0]] = x % 10;
x /= 10;
}
for (int i = num[0]; i >= 1; --i) {
for (int j = 0; j < num[i]; ++j) {
if (j == 4 || (num[i + 1] == 6 && j == 2)) continue;
ans += dp[i][j];
}
if (num[i] == 4) break;
if (num[i + 1] == 6 && num[i] == 2) break;
}
return ans;
}

int main() {
IMPROVE_IO();
Init();
while (true) {
cin >> n >> m;
if (n == 0 && m == 0) break;
cout << Solve((m) + 1) - Solve((n - 1) + 1) << endl;
}
return 0;
}