zoukankan      html  css  js  c++  java
  • CodeForces 258B Little Elephant and Elections 数位DP

    前面先用数位DP预处理,然后暴力计算组合方式即可。

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <climits>
    #include <string>
    #include <iostream>
    #include <map>
    #include <cstdlib>
    #include <list>
    #include <set>
    #include <queue>
    #include <stack>
    
    using namespace std;
    
    typedef long long LL;
    const int maxn = 20;
    const LL MOD = 1e9 + 7;
    int M,lim[maxn],len;
    bool vis[maxn][maxn];
    struct EE {
        LL cnt[maxn];
        EE() {
            memset(cnt,0,sizeof(cnt));
        }
    };
    EE f[maxn][maxn], ans;
    
    void getlim(int num) {
        len = 0;
        memset(lim,0,sizeof(lim));
        while(num) {
            lim[len++] = num % 10;
            num /= 10;
        }
    }
    
    EE dfs(int now,int cnt,int bound) {
        if(now == 0) {
            EE ret;
            ret.cnt[cnt] = 1;
            return ret;
        }
        if(!bound && vis[now][cnt]) return f[now][cnt];
        int m = bound ? lim[now - 1] : 9;
        EE ret;
        for(int i = 0;i <= m;i++) {
            EE nret = dfs(now - 1,cnt + (i == 4 || i == 7),bound && i == m);
            for(int i = 0;i <= len;i++) ret.cnt[i] += nret.cnt[i];
        }
        if(!bound) {
            f[now][cnt] = ret;
            vis[now][cnt] = true;
        }
        return ret;
    }
    
    LL A(LL m,LL n) {
        LL ret = 1;
        for(int i = 1;i <= n;i++) {
            ret *= m; m--; ret %= MOD;
        }
        return ret;
    }
    
    LL rest[maxn],rcnt[maxn];
    LL dfs1(int now,int sum,int limm) {
        if(sum >= limm) return 0;
        if(now == 7) {
            LL ret = 1;
            for(int i = 0;i < limm;i++) if(rcnt[i]) {
                ret = (ret * A(ans.cnt[i],rcnt[i])) % MOD;
            }
            return ret;
        }
        LL ret = 0;
        for(int i = 0;i < limm;i++) if(rest[i]) {
            rcnt[i]++; rest[i]--;
            ret = (ret + dfs1(now + 1,sum + i,limm)) % MOD;
            rcnt[i]--; rest[i]++;
        }
        return ret;
    }
    
    void solve() {
        memset(vis,0,sizeof(vis));
        getlim(M);
        ans = dfs(len,0,1);
        ans.cnt[0]--;
        LL out = 0;
        for(int i = 1;i <= len;i++) if(ans.cnt[i]) {
            memcpy(rest,ans.cnt,sizeof(rest));
            memset(rcnt,0,sizeof(rcnt));
            out = (dfs1(1,0,i) * ans.cnt[i] % MOD + out) % MOD;
        }
        cout << out << endl;
    }
    
    
    int main() {
        cin >> M;
        solve();
        return 0;
    }
    

      

  • 相关阅读:
    互联网协议
    TCP/IP协议三次握手_四次挥手
    nginx重定向rewrite
    创建第一个django工程
    Anaconda-用conda创建python虚拟环境
    数组
    StringBuilder
    杨辉三角
    数据类型和变量
    .net框架中的一些接口
  • 原文地址:https://www.cnblogs.com/rolight/p/3888708.html
Copyright © 2011-2022 走看看