
注意点:
- 边界讨论.
1 #include<cstdio>
2 #include<iostream>
3 #include<cstring>
4 #include<algorithm>
5 using namespace std;
6 const int INF=2e9;
7 int dp[15][15];
8 int num[15];//每一位数字的最大值
9 int dfs(int len,int last,bool isMaxed,bool lead){//lead: 是否有前导零
10 if(len==0)return 1;//递归边界
11 if(!lead&&!isMaxed&&dp[len][last])
12 return dp[len][last];
13 int cnt=0;
14 int nowMaxVal=(isMaxed?num[len]:9);//当前位最大值
15 for(int i=0;i<=nowMaxVal;i++){//枚举当前位数字
16 if(abs(i-last)<2)continue;
17 int nowNum=i;//当前位数字
18 if(lead&&i==0)nowNum=-INF;//继续增加前导零
19 cnt+=dfs(len-1,nowNum,(isMaxed)&&(i==nowMaxVal),(nowNum==-INF));
20 }
21 if(!lead)
22 dp[len][last]=cnt;
23 return cnt;
24 }
25 int solve(int x){
26 int nowDigit=0;//当前位数
27 while(x){//数字分割
28 num[++nowDigit]=x%10;
29 x/=10;
30 }
31 return dfs(nowDigit,-INF,1,1);
32 }
33 int main(){
34 int l,r;
35 scanf("%d%d",&l,&r);
36 printf("%d\n",solve(r)-solve(l-1));
37 return 0;
38 }