枚举数位之和,然后取磨直到最后,记忆化减少时间复杂度。
View Code
1 #include<iostream> 2 #include<cstring> 3 #include<cstdlib> 4 #include<cstdio> 5 typedef long long LL; 6 int const N = 11; 7 int const M = 82; 8 int dp[N][M][M][M]; 9 int bit[N],l,uup; 10 int getsum1(int t,int pre,int sum,int limit,int rest) 11 { 12 if(rest<0)return 0; 13 if(rest>9*t)return 0; 14 if(!t)return (pre%sum==0&&rest==0); 15 if(!limit&&dp[t][pre][sum][rest]!=-1)return dp[t][pre][sum][rest]; 16 int up=(limit?bit[t]:9); 17 LL ans=0LL; 18 for(int i=0;i<=up;i++) 19 { 20 ans+=getsum1(t-1,(pre*10+i)%sum,sum,limit&&i==up,rest-i); 21 } 22 if(!limit&&dp[t][pre][sum][rest]==-1)dp[t][pre][sum][rest]=ans; 23 return ans; 24 } 25 int Max(int a,int b) 26 { 27 return a>b?a:b; 28 } 29 int getsum2(LL n) 30 { 31 int sum=0; 32 for(l=0;n;bit[++l]=n%10,sum+=bit[l],n/=10); 33 int ans=0; 34 uup=Max(bit[l]-1+9*(l-1),sum); 35 for(int i=1;i<=uup;i++) 36 ans+=getsum1(l,0,i,1,i); 37 return ans; 38 } 39 int main() 40 { 41 int T; 42 scanf("%d",&T); 43 int t=0; 44 int a,b; 45 memset(dp,-1,sizeof(dp)); 46 while(T--) 47 { 48 scanf("%d %d",&a,&b); 49 printf("Case %d: %d\n",++t,getsum2(b)-getsum2(a-1)); 50 } 51 return 0; 52 }