传送门
解析:
今天突然发现自己还没写过数位 D P DP DP入门题。。。
思路:
我们从高位向低位DP,采用记忆化搜索。
初始化
f
f
f数组为
−
1
-1
−1,因为我们可能
D
P
DP
DP到某个状态是没有合法数的。
然后就是简单
D
P
DP
DP一下就行了。
代码:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define re register
#define gc getchar
#define pc putchar
#define cs const
inline
int getint(){
re int num;
re char c;
while(!isdigit(c=gc()));num=c^48;
while(isdigit(c=gc()))num=(num<<1)+(num<<3)+(c^48);
return num;
}
inline
void outint(int a){
static char ch[13];
if(a==0)pc('0');
while(a)ch[++ch[0]]=a-a/10*10,a/=10;
while(ch[0])pc(ch[ch[0]--]^48);
}
int len;
int mark[7];
int f[7][10][2];
inline
int dp(int pos,int num,bool limit){
if(pos>len)return 1;
if(~f[pos][num][limit])return f[pos][num][limit];
int res=0,r;
if(limit)r=mark[pos];
else r=9;
for(int re i=0;i<=r;++i){
if(i==4||(num==6&&i==2))continue;
res+=dp(pos+1,i,limit&&i==r);
}
return f[pos][num][limit]=res;
}
int solve(int a){
len=0;
memset(f,-1,sizeof f);
do{
mark[++len]=a-a/10*10;
a/=10;
}while(a);
reverse(mark+1,mark+len+1);
return dp(1,0,1);
}
int l,r;
signed main(){
while(l=getint(),r=getint(),l+r){
outint(solve(r)-solve(l-1));pc('\n');
}
return 0;
}