CodeForces - 258B - B. Little Elephant and Elections(数位dp+dfs)

B. Little Elephant and Elections

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

There have recently been elections in the zoo. Overall there were 7 main political parties: one of them is the Little Elephant Political Party, 6other parties have less catchy names.

Political parties find their number in the ballot highly important. Overall there are m possible numbers: 1, 2, ..., m. Each of these 7 parties is going to be assigned in some way to exactly one number, at that, two distinct parties cannot receive the same number.

The Little Elephant Political Party members believe in the lucky digits 4 and 7. They want to evaluate their chances in the elections. For that, they need to find out, how many correct assignments are there, such that the number of lucky digits in the Little Elephant Political Party ballot number is strictly larger than the total number of lucky digits in the ballot numbers of 6 other parties.

Help the Little Elephant Political Party, calculate this number. As the answer can be rather large, print the remainder from dividing it by 1000000007 (109 + 7).

Input

A single line contains a single positive integer m (7 ≤ m ≤ 109) — the number of possible numbers in the ballot.

Output

In a single line print a single integer — the answer to the problem modulo 1000000007 (109 + 7).

Examples

input

Copy

7

output

Copy

0

input

Copy

8

output

Copy

1440

题意:

给你一个数字m(7<=m<=1e9),从中任取7个不同的正整数,求其中一个数的4和7的个数严格大于其他6个数的4和7的个数之和的方法总数。

思路:

对于区间[1,1e9]内有多少个数字包含的4和7的个数为x(x=0,1,...,10)个,我们可以利用数位dp简单的处理出来。

至于怎么挑,我们枚举我们选的数字中4和7的个数,然后进行搜索,保证搜剩下的6个数中的4和7的个数之和小于我们选的数即可。

注意,0不计算在内,计算包含的4和7的个数为0的数字个数时要减1。

代码:

#include<iostream>
#include<cmath>
#include<iomanip>
#include<cstring>
#include<algorithm>
#include<cstdio>
#include<string>
#include<queue>
#include<vector>
#include<map>
#define ll long long
#define inf 0x3f3f3f3f
#define rep(i,a,b) for(register int i=(a);i<=(b);++i)
using namespace std;
const int maxn=14;
const ll mo=1000000007;
ll n,m,k;
ll dp[maxn][maxn][maxn];
int a[maxn];
ll sum[maxn],c[maxn][maxn];
ll dfs(int pos,int num,int cnt,bool limit)
{
    //cout<<pos<<endl;
    if(num<0) return 0;
    if(pos==-1) return (num==0);
    if(!limit&&dp[pos][num][cnt]!=-1) return dp[pos][num][cnt];
    int up=limit?a[pos]:9;
    ll tmp=0,fg=0;
    rep(i,0,up)
    {
        if(i==4||i==7) fg=1;
        else fg=0;
        tmp+=dfs(pos-1,num-fg,cnt,limit&&(i==a[pos]));
    }
    if(!limit) dp[pos][num][cnt]=tmp;
    return tmp;
}
ll cal(int i,int res)
{
    ll ans=0;
    if(i==7) return 1;
    for(int x=0;x<=10;x++)
    if(sum[x]&&res-x>0)
    {
        sum[x]--;
        ans=(ans+(sum[x]+1)*cal(i+1,res-x)%mo)%mo;
        sum[x]++;
    }
    return ans;
}
void solve(ll x)
{
    memset(dp,-1,sizeof(dp));
    int pos=0;
    while(x)
    {
        a[pos++]=x%10;
        x/=10;
    }
    //cout<<"*";
    for(int i=0;i<=10;i++)
    {
        sum[i]=dfs(pos-1,i,i,1)%mo;
        //cout<<sum[i]<<" ";
    }
    sum[0]--;
    ll ans=0;
    for(int i=10;i>=0;i--)
    if(sum[i]) ans=(ans+sum[i]*cal(1,i)%mo)%mo;
    printf("%lld\n",ans);
}
int main()
{
    int T,cas=1;
    while(scanf("%lld",&n)!=EOF)
    {
        solve(n);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/LSD20164388/article/details/89228006