所有位和最大为81,枚举x为1-81即和为x且该数能被x整除。。卡内存过===
![](https://i-blog.csdnimg.cn/blog_migrate/8f900a89c6347c561fdf2122f13be562.gif)
![](https://i-blog.csdnimg.cn/blog_migrate/961ddebeb323a10fe0623af514929fc1.gif)
1 #include<stdio.h> 2 #include<string.h> 3 int num[15]; 4 int dp[11][82][82][82]; 5 int dfs(int pos,int sum,int lsum,int mod,int limit) 6 { 7 if (pos==0) return sum==lsum&&mod==0; 8 if (!limit&&dp[pos][sum][mod][lsum]!=-1) 9 return dp[pos][sum][mod][lsum]; 10 int i,tmp=limit?num[pos]:9,ans=0; 11 for (i=0;i<=tmp;i++) 12 ans+=dfs(pos-1,sum+i,lsum,(mod*10+i)%lsum,limit&&i==tmp); 13 if (!limit) 14 dp[pos][sum][mod][lsum]=ans; 15 return ans; 16 } 17 int cal(int x) 18 { 19 int cnt=0,ans=0,i; 20 while (x!=0){ 21 num[++cnt]=x%10; 22 x/=10; 23 } 24 for (i=1;i<=81;i++){ 25 ans+=dfs(cnt,0,i,0,1); 26 } 27 return ans; 28 } 29 int main() 30 { 31 int T,t,l,r; 32 // freopen("1001.in","r",stdin); 33 // freopen("1002.out","w",stdout); 34 scanf("%d",&T); 35 memset(dp,-1,sizeof(dp)); 36 for (t=1;t<=T;t++) 37 { 38 scanf("%d%d",&l,&r); 39 printf("Case %d: %d\n",t,cal(r)-cal(l-1)); 40 } 41 }