这是个裸的数位 吧。
求 的就相当于求
表示 枚举到第 位(从高位到底为枚举,这样更有利于处理上限),前一位是 的方案数、
要求 可以转化成为
同时我们要记录两个参数: (上限),当突破上限时
前导零,相当于记录位数
直接记忆化搜索就可以了
#include <bits/stdc++.h>
using namespace std ;
#define clr(a) memset((a),0,sizeof((a)))
typedef long long ll ;
ll a,b ;
ll dp[20][10]; //dp[i][j]表示前i位,前一位为j
int dig[20] ;
ll DP(int k,int last,int SX,int QDL){
if (k==0) return 1 ;
if (!QDL && !SX && dp[k][last]!=-1) return dp[k][last];
int ans=0 ;
for (int i=0;i<=9;i++){
if (SX && i>dig[k]) break ;
if (abs(i-last)<2) continue ;
int t=i ;
if (QDL && !i) t=-10;
ans+=DP(k-1,t,(SX && i==dig[k]),(t==-10)) ;
}
if (!SX && !QDL) dp[k][last]=ans ;
return ans ;
}
ll solve(ll x){
int dsum=0;
clr(dig) ;
memset(dp,-1,sizeof(dp)) ;
while(x){
dig[++dsum]=x%10 ;
x/=10;
}
return DP(dsum,-10,1,1) ;
}
int main(){
scanf("%lld%lld",&a,&b) ;
ll ans=solve(b)-solve(a-1) ;
printf("%lld\n",ans) ;
}