vijos p1848 计数问题 数位dp

描述

试计算在区间 1 到 n 的所有整数中,数字 x(0 ≤ x ≤ 9)共出现了多少次?例如,在 1 到 11 中,即在 1、2、3、4、5、6、7、8、9、10、11 中,数字 1 出现了 4 次。

样例输入1

11 1

样例输出1

4

提示

对于 100%的数据,1≤ n ≤ 1,000,000,0 ≤ x ≤ 9。

 思路

这道题的数据范围不大,可以直接枚举,当然数位dp更快,注意判断前导0即可。

用时

全部1ms
#include <bits/stdc++.h>
#define fu(a, b, c) for (int a = b; a <= c; a++)
#define fd(a, b, c) for (int a = b; a >= c; a--)
using namespace std;
int a[10], dp[10][10][2], n, q, cnt;

int dfs(int pos, int sta, int pre, int limit) {
    if (pos == -1)
        return sta;
    if (!limit && dp[pos][sta][pre] != -1) {
        return dp[pos][sta][pre];
    }
    int up = limit ? a[pos] : 9, tmp = 0;
    fu(i, 0, up) {
        int nsta = q || pre ? sta + (i == q) : sta;
        tmp += dfs(pos - 1, nsta, i || pre, limit && i == a[pos]);
    }
    if (!limit)
        dp[pos][sta][pre] = tmp;
    return tmp;
}

int solve(int x) {
    cnt = 0;
    memset(dp, -1, sizeof dp);
    while (x) {
        a[cnt++] = x % 10;
        x /= 10;
    }
    return dfs(cnt - 1, 0, 0, 1);
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cin >> n >> q;
    cout << solve(n) << '\n';
}

  

  

posted @ 2020-08-12 21:04  lemu  阅读(102)  评论(0编辑  收藏  举报
4