1 #include<cstdio>
 2 #include<iostream>
 3 #include<queue>
 4 #include<algorithm>
 5 #define ll long long
 6 #define M 40009
 7 #define MO 1000000007
 8 using namespace std;
 9 int a[15],tot,K,anss;
10 ll ans[10*M],n,f[15][M][2],size[M],m;
11 struct data
12 {
13     int x,y;
14     ll z;
15     data(int a1,int a2)
16       {
17         x=a1;
18         y=a2;
19         z=size[x]*size[y];
20       }
21     bool operator <(data a1)const
22       {
23         return z<a1.z;
24       }
25 };
26 void dfs(int wei,ll a1,int now)
27 {
28     if(a1>m)
29       return;
30     if(wei==tot)
31       {
32         ans[++ans[0]]=a1;
33         return;
34       }
35     for(int i=now;i<10;i++)
36        dfs(wei+1,a1*i,i);
37     return;
38 }
39 bool cmp(ll a1,ll a2)
40 {
41     return a1>a2;
42 }
43 int main()
44 {
45     scanf("%lld%d",&n,&K);
46     m=n;
47     for(;n;n/=10)
48       a[++tot]=n%10;
49     dfs(0,1,1);
50     sort(ans+1,ans+ans[0]+1);
51     ans[0]=unique(ans+1,ans+ans[0]+1)-ans-1;
52     f[0][1][0]=1;
53     for(int i=0;i<tot;i++)
54       {
55       for(int j=1;j<=ans[0];j++)
56         for(int k=0;k<2;k++)
57           if(f[i][j][k])
58                 for(int l=1;l<10;l++)
59                   {
60                     ll a1=ans[j]*l;
61                     if(a1>ans[ans[0]])
62                       continue;
63                     a1=lower_bound(ans+1,ans+ans[0]+1,a1)-ans;
64                     f[i+1][a1][(k+l)>a[i+1]]+=f[i][j][k];
65                   }
66     }
67     for(int i=1;i<ans[0];i++)
68       for(int j=1;j<tot;j++)
69         size[i]+=f[j][i][0]+f[j][i][1];
70     for(int i=1;i<=ans[0];i++)
71       size[i]+=f[tot][i][0];
72     sort(size+1,size+ans[0]+1,cmp);
73     priority_queue<data> p;
74     p.push(data(1,1));
75     for(;!p.empty();)
76       {
77         K--;
78         data q=p.top();
79         p.pop();
80         anss=(anss+q.z)%MO;
81         if(!K)
82           break;
83         if(q.x!=q.y) 
84           {
85             anss=(anss+q.z)%MO;
86             K--;
87             if(!K)
88                break;
89             p.push(data(q.x+1,q.y));
90           }
91         if(q.x==1)
92           p.push(data(q.x,q.y+1));
93       }
94     printf("%d",anss);
95     return 0;
96 }

DP求出转移到x坐标的数目。各位数乘积的实际数目少。

posted on 2016-03-22 23:20  xiyuedong  阅读(228)  评论(0编辑  收藏  举报