Luo Valley P2602 [ZJOI2010] DP-bit digital count stops title

Topic links: https://www.luogu.com.cn/problem/P2602

Subject to the effect:
the calculation section \ ([L, R] \ ) in the range of \ (0 \ sim 9 \) each appeared many times?

Problem-solving ideas:
the use of digital DP to solve it.
Defines an array of structures \ (f [pos] [all0 ] \) represents the following condition is satisfied \ (0 \ sim 9 \) number of occurrences:

  • Currently located digit for the first \ (pos \) position;
  • \ (all0 \) to \ (1 \) represents the state has always been ahead of the current pre \ (0 \) , is \ (0 \) indicates that an over-digit top front is not \ (0 \) number.

Then define a type of return value of the function for this structure dfs(int pos, int all0, bool limit)solved, wherein:

  • \ (pos \) and \ (all0 \) as defined previously;
  • \ (limit \) indicates whether in the restricted state.

Codes are as follows:

// P2602 [ZJOI2010]数字计数
#include <bits/stdc++.h>
using namespace std;
long long cnt[10], pow10[22], num;
int a[22];
struct Node {
    long long arr[10];
    Node() { memset(arr, 0, sizeof(arr)); }
    void merge(Node v) {
        for (int i = 0; i < 10; i ++)
            arr[i] += v.arr[i];
    }
} f[22][2];
bool vis[22][2];
void init() {
    pow10[0] = 1;
    for (int i = 1; i <= 18; i ++) pow10[i] = pow10[i-1] * 10;
}
Node dfs(int pos, int all0, bool limit) {
    if (pos < 0) return Node();
    if (!limit && vis[pos][all0]) return f[pos][all0];
    int up = limit ? a[pos] : 9;
    Node tmp = Node();
    for (int i = 0; i <= up; i ++) {
        if (i == 0 && all0 && pos>0) ;
        else {
            if (limit && i==up) tmp.arr[i] += num % pow10[pos] + 1;
            else tmp.arr[i] += pow10[pos];
        }
        tmp.merge(dfs(pos-1, all0&&i==0, limit&&i==up));
    }
    if (!limit) {
        vis[pos][all0] = true;
        f[pos][all0] = tmp;
    }
    return tmp;
}
Node get_num(bool minus1) {
    long long x;
    cin >> x;
    if (minus1) x --;
    num = x;
    int pos = 0;
    while (x) {
        a[pos++] = x % 10;
        x /= 10;
    }
    if (num == 0) a[pos++] = 0;
    return dfs(pos-1, true, true);
}
int main() {
    init();
    Node res_l = get_num(true);
    Node res_r = get_num(false);
    for (int i = 0; i < 10; i ++) {
        if (i) putchar(' ');
        cout << res_r.arr[i] - res_l.arr[i];
    }
    cout << endl;
    return 0;
}

Guess you like

Origin www.cnblogs.com/quanjun/p/12005094.html