解析:
预处理:
f[i][j]:表示第i位,最高位为 j
限制条件:最高位不能选4 第i位不能选6且第i-1位不能选2
所以状态转移:f[i][j]+=f[i-1][k] (j!=4 && k!=4 &&(j!=6&&j!=2))
数位dp分析:在树上进行决策
对于第An-1位
0~An-1-1 放到左子树 An-1 放到右子树
计算左子树可能的情况 因为不能存在4或者62连起来的。所以用一个last记录 上一位是什么
满足 (j!=4&&(last!=6&&j!=2) 即可计算答案 res+=f[i+1][j]
#include<bits/stdc++.h>
using namespace std;
const int N=15;
int f[N][N];
int a,b;
void init()
{
for(int i=0;i<=9;i++) if(i!=4) f[1][i]=1;
for(int i=2;i<N;i++)
for(int j=0;j<=9;j++)
for(int k=0;k<=9;k++)
{
if(j==4||k==4||(j==6&&k==2)) continue;
f[i][j]+=f[i-1][k];
}
}
int solve(int n)
{
if(!n) return 1;
vector<int> nums;
while(n) nums.push_back(n%10),n/=10;
int last=0;
int res=0;
for(int i=nums.size()-1;i>=0;i--)
{
int x=nums[i];
for(int j=0;j<x;j++)
{
if(j==4||(last==6&&j==2)) continue;
res+=f[i+1][j];
}
if((last==6&&x==2)||(x==4)) break;
last=x;
if(!i) res++;
}
return res;
}
int main()
{
init();
while(~scanf("%d %d",&a,&b)&&a&&b)
{
printf("%d\n",solve(b)-solve(a-1));
}
}