题意:大概是从1~n中取7个数,左边6个数中的4,或7个数之和小于右边1个数中的4,7个数之和;
先用hash[0~9]存储下前n个数中,4,7个数之和的数字有多少 ,接下来就是组合知识了,这个真心不会
写了好久没写出来,只好百度了QAQ,还是太弱了
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#define maxn 30
#define mod 1000000007
using namespace std;
#define ll long long
ll limit[40],dp[40][400],k;
ll hash[10],sb;
void fun(ll pos,ll x,ll s)//dfs求出所有组合的种类
{
if(pos>5)
{
sb=(sb+s)%mod;
return ;
}
for(ll i=0;i<x;i++)
{
if(hash[i])
{
hash[i]--;
fun(pos+1,x-i,(hash[i]+1)*s%mod);
hash[i]++;
}
}
}
ll dfs(ll now,ll sum,bool flag)
{
if(now<=0) return sum==k;
if(!flag&&dp[now][sum]!=-1) return dp[now][sum];
ll bound=flag?limit[now]:9,ret=0;
for(ll i=0;i<=bound;i++)
{
ret+=dfs(now-1,sum+(i==4)+(i==7),flag&&(i==bound));
}
if(!flag) dp[now][sum]=ret;
return ret;
}
ll count(ll x)
{
ll len=0;
while(x)
{
limit[++len]=x%10;
x/=10;
}
return dfs(len,0,true);
}
int main()
{
ll n;
while(cin>>n)
{
for(k=0;k<=9;k++)//预处理
{
memset(dp,-1,sizeof(dp));
hash[k]=count(n)-count(0);
}
sb=0;
ll i;
for(i=0;i<=9;i++)
{
if(hash[i])
{
hash[i]--;
fun(0,i,hash[i]+1);
hash[i]++;
}
}
cout<<sb<<endl;
}
return 0;
}