• Codeforces 1073 E


    E - Segment Sum

    思路:

    数位dp

    我们平时做的数位dp都是求满足条件的数的个数, 这里要求满足条件的数的和

    只要在原来的基础上求每一位的贡献就可以了,所以传参数时要传两个

    代码:

    #pragma GCC optimize(2)
    #pragma GCC optimize(3)
    #pragma GCC optimize(4)
    #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 pli pair<LL, int>
    #define pii pair<int, int>
    #define piii pair<pii, 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
    
    const int MOD = 998244353;
    int k;
    pll dp[20][1025];
    int a[20], tot;
    LL pw[20];
    pll dfs(int pos, int s, bool zero, bool limit) {
        if(!pos) return {__builtin_popcount(s) <= k, 0};
        if(!limit && !zero && ~dp[pos][s].fi) return dp[pos][s];
        int up = 9;
        if(limit) up = a[pos];
        pll ans = {0, 0};
        for (int i = 0; i <= up; i++) {
            pll res;
            if(zero && i == 0) res = dfs(pos-1, s, zero, limit&&i==up);
            else res = dfs(pos-1, s|(1<<i), zero&&i==0, limit&&i==up);
            (ans.fi = ans.fi + res.fi) %= MOD;
            (ans.se = ans.se + res.se + i*res.fi%MOD*pw[pos-1]%MOD) %= MOD;
        }
        if(!limit && !zero) dp[pos][s] = ans;
        return ans;
    }
    void init() {
        pw[0] = 1;
        for (int i = 1; i < 20; i++) pw[i] = (pw[i-1] * 10) % MOD;
        for (int i = 0; i < 20; i++)
            for (int j = 0; j < 1025; j++) dp[i][j].fi = dp[i][j].se = -1;
    }
    LL solve(LL n) {
        tot = 0;
        init();
        while(n) {
            a[++tot] = n % 10;
            n /= 10;
        }
        return dfs(tot, 0, 1, 1).se;
    
    }
    int main() {
        LL l, r;
        scanf("%lld %lld %d", &l, &r, &k);
        printf("%lld
    ", (solve(r) - solve(l-1) + MOD) % MOD);
        return 0;
    }
  • 相关阅读:
    基础DP(初级版)
    UVA-816.Abbott's Tevenge (BFS + 打印路径)
    1044: 数圈
    1049: 打牌
    1047: 小A的计算器
    1046: 最小的K个数
    1045: 愚人节的礼物
    1044: 数圈
    1043: 绩点计算
    1042: 小丑排序
  • 原文地址:https://www.cnblogs.com/widsom/p/9951706.html
Copyright © 2020-2023  润新知