主要是记录一个flag,表示现在距离幸运位的位置有多远,然后做一下记忆化的搜索就OK了。。
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 #include<cmath> 6 #define MOD 1000000007 7 using namespace std; 8 typedef long long LL; 9 int const N = 2010; 10 int ln,k; 11 char bitl[N],bitr[N]; 12 LL dp[N][N]; 13 LL getsum1(int t,int limit,int flag,char b[]) 14 { 15 if(t==ln) 16 { 17 return (flag==0); 18 } 19 int up=(limit?(b[t]-'0'):9); 20 if(!limit&&dp[ln-t][flag]!=-1)return dp[ln-t][flag]; 21 LL ans=0; 22 for(int i=0;i<=up;i++) 23 { 24 25 int f=(flag==0?0:flag+1); 26 if((i==4||i==7)) 27 { 28 if(flag<=k)f=0; 29 else f=1; 30 } 31 ans=(ans+getsum1(t+1,limit&&i==up,f,b))%MOD; 32 } 33 if(!limit&&dp[ln-t][flag]==-1)dp[ln-t][flag]=ans; 34 return ans; 35 } 36 int main() 37 { 38 int n; 39 pre(); 40 memset(dp,-1,sizeof(dp)); 41 scanf("%d %d",&n,&k); 42 for(int i=0;i<n;i++) 43 { 44 scanf("%s",bitl); 45 ln=strlen(bitl); 46 int j=0; 47 while(bitl[ln-j-1]<'1')bitl[ln-j-1]='9',j++; 48 bitl[ln-j-1]=bitl[ln-j-1]-1; 49 for(j=0;bitl[j]=='0';j++); 50 LL ans1=getsum1(j,1,k+2,bitl); 51 scanf("%s",bitr); 52 ln=strlen(bitr); 53 LL ans2=getsum1(0,1,k+2,bitr); 54 printf("%I64d\n",((ans2-ans1)%MOD+MOD)%MOD); 55 } 56 return 0; 57 }