给出一段区间a-b,统计这个区间内0-9出现的次数。
数位dp
#include <bits/stdc++.h> #include <iostream> #include <string.h> #include <math.h> using namespace std; typedef long long ll; const ll mod = 1e9 + 7; const int maxn = 22; int digit[maxn], tot, d; ll dp[maxn][22][22]; ll dfs(int len, int top, int sum, int limit, int p) { if (!len) return sum; if (!limit && dp[len][top][sum] != -1) return dp[len][top][sum]; int up = (limit?digit[len]:9); ll res = 0; for (int i = 0; i <= up; i++) { if(top == 0) { if (i == 0) { res += dfs(len - 1, i, sum, (limit && (i == up)), p); } else { res += dfs(len - 1, i, sum + (i == p), (limit && (i == up)), p); } } else { res += dfs(len - 1, top, sum + (i == p), (limit && (i == up)), p); } } if (!limit) dp[len][top][sum] = res; return res; } ll ans[10][2]; void solve(ll n, int p) { tot = 0; while (n) { digit[++tot] = n % 10; n /= 10; } for (int i = 0; i <= 9; i++) { memset(dp, -1, sizeof(dp)); ans[i][p] = dfs(tot, 0, 0, 1, i); } } int main() { //freopen("in.in", "r", stdin); // freopen("o2.out", "w", stdout); ll l, r; cin >> l >> r; solve(r, 1);solve(l - 1, 0); for (int i = 0; i <= 9; i++) { cout << ans[i][1] - ans[i][0] << endl; } return 0; }