hdu

链接:https://vjudge.net/problem/HDU-2089
思路:数位dp入门题,dp[pos][sta]表示枚举到第len位,sta表示前面是否为6,然后dfs时还有一个limit表示是否严格小于,然后根据limit决定枚举结束的位置,然后转移即可,最后我们只保留严格小于时的答案。

代码:

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

using namespace std;

typedef long long ll;
ll dp[7][2];

int num[10];


ll (int pos, bool limit, bool sta){
if(pos < 0) return 1;

if(dp[pos][sta] != -1 && !limit)return dp[pos][sta];
//决定结束位置
int e = !limit ? 9 : num[pos];
ll ans = 0;
for(int i = 0; i <= e; i++){
if(sta && i == 2)continue;
if(i == 4)continue;
ans += dfs(pos - 1, limit && i == num[pos], i == 6);
}
//如果严格小于,就保存答案
if(!limit) dp[pos][sta] = ans;
return ans;
}

ll solve(int x){
int pos = 0;
while(x){
num[pos++] = x % 10;
x /= 10;
}
return dfs(pos - 1, true, false);
}

int main(){
int l, r;
while(cin >> l >> r && (l || r)) {
memset(dp, -1, sizeof(dp));
cout << solve(r) - solve(l - 1) << 'n';
}
return 0;
}