Codeforces 258B - Little Elephant and Elections

来源:互联网 发布:自学电脑办公软件 编辑:程序博客网 时间:2024/05/22 14:07

[1,m]中依次选择7个数,满足前六个数中47的个数之和小于最后一个数的47的个数的方案数(mod1e9+7)


我们按照4和7的个数对[1,m]的数做等价类划分。然后dfs就好。前半部分可以用数位dp解决。

#include<bits/stdc++.h>using namespace std;const int maxn = 12,mod = 1e9+7;#define LL long long  LL dp[maxn][2][maxn];int num[maxn];LL dfs(int pos,bool bnd,int ned){    if(ned < 0) return 0;    if(pos < 0) return ned == 0;    LL & ndp = dp[pos][bnd][ned];    if(~ndp) return ndp;    ndp = 0;    int bound = bnd ? num[pos] : 9 ;    for(int i=0;i<=bound;i++)        ndp += dfs(pos-1,bnd && i == bound,ned - (i==4||i==7) );    return ndp;}LL cnt[maxn];int init(LL x){    int len = 0;    while(x){        num[len++] = x % 10;        x /= 10;    }    memset(dp,-1,sizeof(dp));    for(int i=len;i>=0;i--){        cnt[i] = dfs(len-1,true,i);    }    cnt[0]--;    return len;}LL ans;void dfs(int st,LL v,int len,int adder){    if(st == 7){        for(int i=adder+1;i<=len;i++){            (ans += v * cnt[i] % mod) %= mod;        }        return;    }    if(adder >= len) return;    for(int i=0;i<=len;i++){        if(cnt[i] == 0) continue;        LL mid = v * cnt[i] % mod;        cnt[i]--;        dfs(st+1,mid,len,adder+i);        cnt[i]++;    }}int main(){    LL n;    scanf("%I64d",&n);    int len = init(n);    ans = 0;    dfs(1,1,len,0);    printf("%I64d\n",ans);    return 0;}
0 0
原创粉丝点击