隐藏
「hzwer5527」准考证 - 数位动规 | Bill Yang's Blog

路终会有尽头,但视野总能看到更远的地方。

0%

「hzwer5527」准考证 - 数位动规

题目大意

    蒟蒻hzwer NOIP2014惨跪,他依稀记得他的准考证号是$37$,现在hzwer又将要面临一场比赛,他希望准考证号不出现$37$(连续),同时他又十分讨厌$4$,所以也不希望$4$出现在准考证号中……现在他想知道在$A$和$B$之间(包括$A$和$B$)有多少合法的准考证号。


题目分析

比较裸的数位动规。


代码

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
#include<algorithm>
#include<iostream>
#include<iomanip>
#include<cstring>
#include<cstdlib>
#include<vector>
#include<cstdio>
#include<cmath>
#include<queue>
using namespace std;
typedef long long LL;
inline const LL Get_Int() {
LL num=0,bj=1;
char x=getchar();
while(x<'0'||x>'9') {
if(x=='-')bj=-1;
x=getchar();
}
while(x>='0'&&x<='9') {
num=num*10+x-'0';
x=getchar();
}
return num*bj;
}
LL x,y,f[15][15][2],a[15],cnt=0;
LL Dp(int Now,int last,bool up) {
if(Now>cnt)return 1;
if(~f[Now][last][up])return f[Now][last][up];
f[Now][last][up]=0;
int limit=up?a[Now]:9;
for(int i=0; i<=limit; i++) {
if(i==4)continue;
if(!(last==3&&i==7))f[Now][last][up]+=Dp(Now+1,i,up&&i==limit);
}
return f[Now][last][up];
}
LL Solve(LL x) {
cnt=0;
while(x) {
a[++cnt]=x%10;
x/=10;
}
memset(f,-1,sizeof(f));
reverse(a+1,a+cnt+1);
return Dp(1,0,1);
}
int main() {
x=Get_Int();
y=Get_Int();
printf("%lld\n",Solve(y)-Solve(x-1));
return 0;
}
姥爷们赏瓶冰阔落吧~