数位dp第二道~就当成搜索,套板子写了写。我写的dp[pos][pre][state0]记录的是当前pos位没有限制时、前面的数是pre时、前面是否都是0时的方案数。
1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #include <algorithm> 5 using namespace std; 6 7 typedef long long ll; 8 int n, m, cnt, a[11]; 9 ll dp[11][10][2]; 10 11 ll dfs(int pos, int pre, int state0, int limit) { 12 if (!pos) return 1; 13 if (!limit && dp[pos][pre][state0] >= 0) return dp[pos][pre][state0]; 14 15 int high = limit ? a[pos] : 9; 16 ll ret = 0; 17 for (int low = 0; low <= high; low++) { 18 if (abs(low - pre) < 2 && !state0) continue; 19 ret += dfs(pos - 1, low, (low == 0) & state0, (low == a[pos]) & limit); 20 } 21 22 if (!limit) dp[pos][pre][state0] = ret; 23 return ret; 24 } 25 26 ll solve(int x) { 27 for (cnt = 0; x; x /= 10) 28 a[++cnt] = x % 10; 29 return dfs(cnt, -1, 1, 1); 30 } 31 32 int main() { 33 memset(dp, -1, sizeof dp); 34 cin >> n >> m; 35 cout << solve(m) - solve(n - 1) << endl; 36 return 0; 37 }