D - windy数
windy定义了一种windy数。不含前导零且相邻两个数字之差至少为2的正整数被称为windy数。 windy想知道,
在A和B之间,包括A和B,总共有多少个windy数?
题解:用dp[i][j]表示对前i位,在第i+1位为j时的windy数
代码解释:
/***********************************************/
int a[20];
ll dp[20][11];//记录前i位中windy数个数
//因为前一位j为多少对后面的枚举是有影响的
ll dfs(int cur,int pre,bool limit,bool lead)
{ //lead用于判断从高位到低位枚举时有没有前导0,
//如对1232
//当前面几位枚举的都是0时,后面一位的枚举是不受前面一位限制的,
//因为如果前面几位都是0,就相当于前几位是不存在的,
//所以才有: if( abs(i-pre) >=2 || lead)
//这就是枚举条件
if(cur==0) return 1;
if(!limit && dp[cur][pre]!=-1 && pre>0) return dp[cur][pre];
// pre>0 ,如果pre==0,涉及到位数,需要再次循环
ll ans=0;
int cu=limit?a[cur]:9;
for(int i=0;i<=cu;i++)
{
if( abs(i-pre) >=2 || lead){
//cout<<cur<<" "<<i<<" "<<endl;;
ans+=(dfs(cur-1,i,limit & (i==a[cur]) , lead&(i==0) ));
}
}
if(!limit) dp[cur][pre]=ans;//还是那个记忆化
return ans;
}
ll solve(ll x)
{
int cut=0;
while(x){
a[++cut]=(x%10);
x/=10;
}
return dfs(cut,-2,1,1);
}
int main()
{
ll a,b;
while(cin>>a>>b)
{
mem1(dp);
cout<<solve(b)-solve(a-1)<<endl;
//cout<<solve(10);
}
return 0;
}