注意点:
- 边界讨论.
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 }