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), " 
"[i==9]);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/widsom/p/9293213.html