统计数字当中出现13的子串,并且能被13整除的数字。
逐位确定一下就Ok了,然后加好其他限定条件,减少时间复杂度用记忆化。
View Code
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<cstdlib> 5 typedef long long LL; 6 int const N = 20; 7 int const M = 15; 8 int bit[N],l; 9 LL dp1[N][M][M],dp2[N][M][M]; 10 LL getsum1(int t,int pre,int limit,int last,int flag) 11 { 12 if(!t)return (pre==0&&flag); 13 if(!limit&&flag&&dp1[t][pre][last]!=-1)return dp1[t][pre][last]; 14 if(!limit&&!flag&&dp2[t][pre][last]!=-1)return dp2[t][pre][last]; 15 int up=(limit?bit[t]:9); 16 LL ans=0LL; 17 for(int i=0;i<=up;i++) 18 { 19 ans+=getsum1(t-1,(pre*10+i)%13,limit&&i==up,i,(last==1&&i==3)||flag); 20 } 21 if(!limit&&flag&&dp1[t][pre][last]==-1)dp1[t][pre][last]=ans; 22 if(!limit&&!flag&&dp2[t][pre][last]==-1)dp2[t][pre][last]=ans; 23 return ans; 24 } 25 LL getsum2(LL n) 26 { 27 for(l=0;n;bit[++l]=n%10,n/=10); 28 return getsum1(l,0,1,-1,0); 29 } 30 int main() 31 { 32 LL n; 33 memset(dp1,-1,sizeof(dp1)); 34 memset(dp2,-1,sizeof(dp2)); 35 while(~scanf("%I64d",&n)) 36 { 37 printf("%I64d\n",getsum2(n)); 38 } 39 return 0; 40 }