Codeforces Round #157 (Div. 1)B 數位dp
//枚舉有幾個(7或4),用數位dp的記憶化搜索找有i個(7或4)的數又多少個
//暴力搜索在第i個中選幾個
#include
#include
#include
using namespace std ;
const int mod = 1e9 + 7;
int dp[20][20];//第i位有 j個數(7或者4)
int bit[20] ;
int temp[20];
int luck[20];
int dfs(int pos , int flag ,int max_flag, int lim)
{
if(pos == 0)
return flag == max_flag;
if(!lim && dp[pos][flag] != -1)
return dp[pos][flag] ;
int num = lim ? bit[pos] : 9;
int ans = 0 ;
for(int i = 0;i <= num ;i++)
{
int flag_x = flag ;
if(i == 7 || i == 4)
flag_x++;
ans += dfs(pos - 1 ,flag_x ,max_flag, lim && (i==num)) ;
}
if(!lim)dp[pos][flag] = ans ;
return ans ;
}
//__int64 ans_ans = 0;
__int64 dfs_s(int res , __int64 ans ,int pos, int num ,int max_flag)
{
if(num >= max_flag)
return 0;
if(res == 0)
return (ans * (__int64)temp[num+1])%mod;
__int64 sum = 0;
for(int i = 0 ;i <= pos;i++)
{
if(luck[i] > 0)
{
__int64 ans_x = ((ans*(__int64)luck[i])%mod);
luck[i] -= 1;
sum += dfs_s(res - 1 , ans_x , pos , num+i , max_flag) ;
luck[i] += 1;
}
}
return sum%mod;
}
__int64 solve(int n)
{
if(n == 7)return 0;
int t = n;
int pos = 0;
while(t)
{
bit[++pos] = t%10 ;
t/=10 ;
}
memset(luck , 0 ,sizeof(luck)) ;
memset(temp , 0 , sizeof(temp));
for(int i = pos;i >= 0 ;i--)
{
memset(dp , -1 , sizeof(dp)) ;
luck[i] = dfs(pos , 0 , i , 1) ;
temp[i] = temp[i+1] + luck[i];
}
luck[0] -= 1;
return dfs_s(6 , 1 , pos , 0 , luck[pos] ? pos : pos - 1) ;
}
int main()
{
// freopen("input.txt" ,"r" ,stdin) ;
int n ;
while(~scanf("%d" ,&n))
{
printf("%I64d\n" ,solve(n)%mod) ;
}
return 0;
}