依然按照数位dp的套路,利用前缀和思想,先求
f
(
a
)
:
0
到
a
的
w
i
n
d
y
数
f(a):0到a的windy数
f(a):0到a的windy数
状态为
d
p
(
c
u
r
,
t
o
p
)
dp(cur,top)
dp(cur,top)表示当前选到
c
u
r
cur
cur位,是否贴着上界
t
o
p
top
top
然而这种状态表示存在两个问题:
1.当前选择
c
u
r
cur
cur位的数字的时候,会被上一个选择的数字是什么限制.
比如上一位选的数字是
1
1
1,那么
2
,
0
2,0
2,0这两个数字就不能选择.需要新增一个状态维度
p
r
e
pre
pre,表示上一个数字是
p
r
e
pre
pre
2.前导0的问题
比如说
0063
0063
0063,事实上只算作
63
63
63
而如果不考虑该状态,会有一些选了0063的状态被重复选择,所以需要这个状态来避免重复计算
综上,有四个状态
d
p
(
c
u
r
,
p
r
e
,
t
o
p
,
s
t
)
:
选到了第
c
u
r
个数字
,
前一个数字是
p
r
e
,
是否贴着上界
,
是否前边全部是
0
(
前导
0
状态
)
dp(cur,pre,top,st):选到了第cur个数字,前一个数字是pre,是否贴着上界,是否前边全部是0(前导0状态)
dp(cur,pre,top,st):选到了第cur个数字,前一个数字是pre,是否贴着上界,是否前边全部是0(前导0状态)
/*
I don't wanna be left behind,Distance was a friend of mine.
Catching breath in a web of lies,I've spent most of my life.
Catching my breath letting it go turning my cheek for the sake of this show
Now that you know this is my life I won't be told what's supposed to be right
Catch my breath no one can hold me back I ain't got time for that.
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn = 20;
const int INF = 1e9+7;
typedef long long ll;
typedef pair<int,int> pii;
#define all(a) (a).begin(), (a).end()
#define pb(a) push_back(a)
vector<int> G[maxn];
int dp[maxn][maxn][2][2];
int a[maxn];
int len = 0;
int dfs(int cur,int pre,bool top,bool st){
if(!cur) return 1;
int &ans = dp[cur][pre][top][st];
if(ans!=-1) return ans;
ans = 0;
int bound = top ? a[cur] : 9;
for(int i=0;i<=bound;i++){
if((abs(i-pre)>=2)||(st==1)){
ans+=dfs(cur-1,i,top&&i==bound,st&&(i==0));
}
}
return ans;
}
int solve(int n){
len = 0;memset(dp,-1,sizeof(dp));
while(n) a[++len] = n%10,n/=10;
return dfs(len,11,1,1);
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
int a,b;cin>>a>>b;
cout<<(solve(b)-solve(a-1))<<"\n";
}