思路:简单数位DP,dp[pos][pre]表示枚举到pos位时前一位为pre。
考虑前导0以及数据范围自然溢出。
Code:
#include <bits/stdc++.h>
#define LL unsigned long long
using namespace std;
const int AX = 20+2;
int a[AX];
LL dp[AX][15];
LL dfs( int pos , int pre , bool lead , bool lim ){
if( pos == -1 ) return 1;
if( !lim && !lead && dp[pos][pre] != -1 ) return dp[pos][pre];
LL ans = 0;
int up = lim ? a[pos] : 9 ;
for( int i = 0 ; i <= up ; i++ ){
if( pre == -1 || abs( pre - i ) >= 2 ){
if( lead && i == 0 ) ans += dfs( pos - 1 , pre , lead, lim && i == a[pos]);
else ans += dfs( pos - 1 , i , lead && i == 0 , lim && i == a[pos] );
}
}
if( !lim && !lead ) dp[pos][pre] = ans;
return ans ;
}
LL solve( LL x ){
int tot = 0 ;
while( x ){
a[tot++] = x % 10;
x /= 10;
}
return dfs( tot - 1 , -1 , true , true );
}
int main(){
LL l , r;
cin >> l >> r;
memset( dp , -1 , sizeof(dp) );
//printf("%lld\n",solve(r)-solve(l-1));
cout << solve(r) - solve(l-1);
return 0 ;
}