HDU-2089 不要62

思路:
数位dp的入门题,主要是为了对数位dp有一个初步的认识。我一开始认为数位dp是对左右区间进行dp,不过在看了几篇博客后认识到了应当对当前位以i为第一位的数作为状态来dp。递推式还是比较简单的。

代码:

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
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#define INF 1e9
#define ll long long
#define ms(a,val) memset(a,val,sizeof(a))
#define lson(x) (x<<1)
#define rson(x) (x<<1)+1
#define MOD 1000000007

using namespace std;
int dp[10][10];
void init() {
ms(dp, 0);
dp[0][0] = 1;
for (int i = 1;i <= 7;i++) {
for (int j = 0;j <10;j++) {
for (int k = 0;k < 10;k++) {
if (j != 4 && !(j == 6 && k == 2)) {
dp[i][j] += dp[i - 1][k];
}
}
}
}
}
int solve(int n) {
int t = n,length=0, digit[10],ans=0;
while (t > 0) {
digit[++length] = t % 10;
t /= 10;
}
digit[length+1] = 0;
for (int i = length ;i > 0;i--) {
for (int j = 0;j < digit[i];j++) {
if (j != 4 && !(digit[i + 1] == 6 && j == 2))ans += dp[i][j];
}
if (digit[i] == 4 || (digit[i] == 2 && digit[i + 1] == 6))break;
}
return ans;
}
int main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
int l, r;
init();
while (cin>>l>>r) {
if (l + r == 0)break;
cout << solve(r + 1) - solve(l) << "\n";
}
return 0;
}