BZOJ 1833: [ZJOI2010]count 数字计数
1833
思路:数位dp
代码:
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head LL dp[20][20][2]; int a[20], cnt; LL dfs(int x, int pos, int res, bool zero, bool limit) { if(pos == -1) return res; if(!limit && ~dp[pos][res][zero]) return dp[pos][res][zero]; int up = 9; if(limit) up = a[pos]; LL ans = 0; for (int i = 0; i <= up; i++) { if(zero) { if(i == 0 && x == 0) ans += dfs(x, pos-1, res, zero&&i==0, limit&&i==up); else if(i == x) ans += dfs(x, pos-1, res+1, zero&&i==0, limit&&i==up); else ans += dfs(x, pos-1, res, zero&&i==0, limit&&i==up); } else { if(i == x) ans += dfs(x, pos-1, res+1, zero&&i==0, limit&&i==up); else ans += dfs(x, pos-1, res, zero&&i==0, limit&&i==up); } } if(!limit) dp[pos][res][zero] = ans; return ans; } LL solve(LL n, int x) { if(n == 0) return 0; cnt = 0; while(n) { a[cnt++] = n%10; n /= 10; } mem(dp, -1); return dfs(x, cnt-1, 0, 1, 1); } int main() { LL a, b; scanf("%lld %lld", &a, &b); for (int i = 0; i <= 9; i++) { printf("%lld%c", solve(b, i) - solve(a-1, i), " \n"[i==9]); } return 0; }