1. 程式人生 > 實用技巧 >CF1036C Classy Numbers 題解 數位DP

CF1036C Classy Numbers 題解 數位DP

題目連結:https://codeforces.com/problemset/problem/1036/C

題目大意:求區間 \([L,R]\) 範圍內非零數字位數不超過 \(3\) 個的數字個數。

解題思路:數位DP。\(f[p][num]\) 表示到第 \(p\) 位為止有 \(num\) 個非零數字的數的個數。

示例程式碼:

#include <bits/stdc++.h>
using namespace std;
long long f[20][4], a[20];
bool vis[20][4];
long long dfs(int p, int num, bool limit) {
    if (num > 3) return 0;
    if (p < 0) return 1;
    if (!limit && vis[p][num]) return f[p][num];
    if (!limit) vis[p][num] = true;
    int up = limit ? a[p] : 9;
    long long ans = 0;
    for (int i = 0; i <= up; i ++) {
        ans += dfs(p-1, num + (i!=0), limit && i==up);
    }
    if (!limit) f[p][num] = ans;
    return ans;
}
long long handle(long long num) {
    int p = 0;
    while (num) {
        a[p++] = num % 10;
        num /= 10;
    }
    return dfs(p-1, 0, true);
}
int T;
long long L, R;
int main() {
    scanf("%d", &T);
    while (T --) {
        scanf("%lld%lld", &L, &R);
        printf("%lld\n", handle(R) - handle(L-1));
    }
    return 0;
}