• CF258B


    CF258B

    题意:

    7个人在 $ [1,m] $ 区间内取数,求第一个人选的数的4和7的个数大于其他人的4和7个数总和的方案数。

    解法:

    要求输入的 $ m $ 可以很大,而且需要按位考虑每隔人的贡献,所以考虑数位DP。
    设 $ f[i][j] $ 表示到第 $ i $ 位,有 $ j $ 个数是 $ 4 和 7 $ 的方案数,再利用dfs进行转移就行。

    CODE :

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    
    using namespace std;
    
    #define LL long long
    const LL MOD = 1e9+7;
    
    LL final,dp[16][16],c[16];
    int bit[16],l,cnt,tot,m;
    
    int work(int m, int n) {
        cnt = tot = l = 0;
        for (; m; m /= 10) bit[++l] = m % 10;
        for (int i = l; i && tot <= n; --i) {
            for(int j = 0 ; j < bit[i] ; j++)
                if (j == 4 || j == 7) {
                    if (tot < n) cnt += dp[i - 1][n - tot - 1];
                } else cnt += dp[i - 1][n - tot];
            if (bit[i] == 4 || bit[i] == 7) ++tot;
        }
        if(tot == n) ++cnt;
        if(n == 0) --cnt;
        return cnt;
    }
    void dfs(int t, int now, int lim, LL ans) {
        if (t == 6) (final += ans) %= MOD;
        else {
            for (int i = 0; i <= 9 && i + now < lim; ++i)
                if (c[i]) {
                    c[i]--;
                    dfs(t + 1, now + i, lim, ans * (c[i] + 1) % MOD);
                    c[i]++;
                }
        }
    }
    
    int main() {
        scanf("%d", &m);
        dp[0][0] = 1;
        for(int i = 0 ; i <= 9 ; i++) {
            for(int j = 0 ; j <= i ; j++) {
                dp[i + 1][j + 1] += dp[i][j] * 2; 
                dp[i + 1][j] += dp[i][j] * 8;
            }
        } 
        for(int i = 0 ; i <= 9 ; i++) c[i] = work(m, i);
        for(int i = 0 ; i <= 9 ; i++) {
                if (c[i]) {
                --c[i];
                dfs(0, 0, i, (c[i] + 1) % MOD);
                ++c[i];
            }
        }
        printf("%lld 
    ", final);
        //system("pause");
        return 0;
    }
    
  • 相关阅读:
    css-深入理解margin和padding
    js的自定义事件
    jcFlexible.js的小Demo
    volatile关键字回顾
    threadLocalMap理解
    常用SQL笔记
    MyISAM和innoDB对比,覆盖索引简单回顾
    经典算法回顾:两个队列生成一个栈,两个栈生成一个队列
    Memcached与Redis对比,Redis基础笔记回顾
    ES(ElasticSearch)学习总结
  • 原文地址:https://www.cnblogs.com/Repulser/p/11373454.html
Copyright © 2020-2023  润新知