喜闻乐见的数位入门第一道,这个dp[pos][state]记录的是第pos位如果没有限制的话(有限制当然要搜一搜暴力数了),前一位 放6 or 不放6 的方案数。也就是并不是要求的答案,其实就是记忆化一下,减小搜索的复杂度,跟dp没啥关系吧……
1 int n, m, cnt; 2 ll a[10], dp[10][2]; 3 4 ll dfs(int pos, int pre, int state, int limit) { 5 if (!pos) return 1; 6 if (!limit && dp[pos][state] >= 0) return dp[pos][state]; 7 8 int up = limit ? a[pos] : 9; 9 ll ret = 0; 10 rep(i, 0, up) { 11 if (i == 4 || (pre == 6 && i == 2)) continue; 12 ret += dfs(pos - 1, i, i == 6, limit & (i == a[pos])); 13 } 14 15 if (!limit) dp[pos][state] = ret; 16 return ret; 17 } 18 19 ll solve(int x) { 20 for (cnt = 0; x; x /= 10) 21 a[++cnt] = x % 10; 22 return dfs(cnt, -1, 0, 1); 23 } 24 25 int main() { 26 init(dp, -1); 27 while (~scanf("%d %d", &n, &m) && (n | m)) { 28 writeln(solve(m) - solve(n - 1)); 29 } 30 return 0; 31 }