入门题。就是数位上不能有4也不能有连续的62,没有4的话在枚举的时候判断一下,不枚举4就可以保证状态合法了,所以这个约束没有记忆化的必要,而对于62的话,涉及到两位,当前一位是6或者不是6这两种不同情况我计数是不相同的,所以要用状态来记录不同的方案数。
dp[pos][sta]表示当前第pos位,前一位是否是6的状态,这里sta只需要去0和1两种状态就可以了,不是6的情况可视为同种,不会影响计数。
#include <bits/stdc++.h>
using namespace std;
const int maxn = 10;
int dp[maxn][2];
int a[maxn];
int n,m;
int dfs(int pos, bool lastnum, bool lead, bool limit){
if(pos == -1) return 1;
if(!limit && dp[pos][lastnum] != -1) return dp[pos][lastnum];
int up = (limit) ? a[pos] : 9;
int ans = 0;
for(int j = 0;j <= up;j++){
if(j == 4) continue;
if((lastnum == 0) && j == 2) continue;
int newlast = !(j == 6);
ans += dfs(pos - 1, newlast, lead && (j == 0), limit && (j == up));
}
if(!limit && dp[pos][lastnum] == -1) dp[pos][lastnum] = ans;
return ans;
}
int solve(int n){
int pos = 0;
while(n > 0) {
a[pos++] = n % 10;
n/=10;
}
return dfs(pos - 1, 1, true, true);
}
int main()
{
memset(dp,-1,sizeof(dp));
while(~scanf("%d%d",&n,&m)){
if(n == 0 && m == 0) break;
printf("%d\n",solve(m) - solve(n - 1));
}
return 0;
}