洛谷 P11557 [ROIR 2016] 有趣数字 (Day 2)

题意

找到\([l,r]\)中有趣数字个数

有趣数字 : 从高位到低位数码单调不减
数据范围 : \(10^{100}\)

思路

数位dp , 注意要用string存

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long int
inline int read() {
    int ans = 0, f = 1;
    char ch = getchar();
    while (ch < '0' || ch > '9') {
        if (ch == '-')f = -1;
        ch = getchar();
    }
    while (ch <= '9' && ch >= '0') {
        ans = ans * 10 + ch - '0';
        ch = getchar();
    }
    return ans * f;
}
int a[110];
int f[110][10];
const int mod = 1e9+7;
int dfs(int pos, int pre,bool limit) {
    if (!pos)   return 1;
    if (!limit && f[pos][pre]>=0) return f[pos][pre];
    int up = limit?a[pos]:9;
    int ans = 0;
    for (int i =0 ; i<= up; i++) {
        if (i>=pre) ans = (ans + dfs(pos-1,i,limit && i==up))%mod;
    }
    if (!limit) f[pos][pre] = ans;
    return ans;
}
int work(string x) {
    int cnt = 0;
    for (auto e: x) {
        a[++cnt] = e-'0';
    }
    reverse(a+1,a+1+cnt);
    return dfs(cnt,0,true);
}
string dec(string s) {
    int i = s.size()-1;
    while (s[i] =='0') {
        s[i] = '9';
        i--;
    }
    s[i]--;
    return s;
}
signed main() {
    memset(f,-1,sizeof f);
    string l,r;
    cin>>l>>r;
    string ll = dec(l);
    cout<<(work(r)-work(ll) + mod )%mod<<"\n";
    return 0;
}
posted @ 2025-05-12 21:53  Guaninf  阅读(4)  评论(0)    收藏  举报