常规数位dp题,对于不同k分开记忆化。注意:k大于82(1999999999的数位和)时不会有答案,直接输出0即可。还有,按照这种记录不同k时的答案的做法需要卡一下空间。
错误1次原因:没有卡空间
1 #include<cstdio> 2 #include<cstring> 3 int ans[83][11][83][83]; 4 int a,b,k,T,TT; 5 int w[12]; 6 int dp(int pos,int r,int sum,bool pre0,bool limit) 7 { 8 if(pos<1) return r==0&&sum%k==0&&!pre0; 9 if(!limit&&ans[k][pos][r][sum]!=-1) 10 return ans[k][pos][r][sum]; 11 int i,end=limit?w[pos]:9,res=0; 12 for(i=0;i<=end;i++) 13 res+=dp(pos-1,(r*10+i)%k,sum+i,pre0&&i==0,limit&&i==w[pos]); 14 return limit?res:ans[k][pos][r][sum]=res; 15 } 16 int get(int x) 17 { 18 int g=0; 19 for(;x>0;x/=10) w[++g]=x%10; 20 return dp(g,0,0,1,1); 21 } 22 int main() 23 { 24 memset(ans,-1,sizeof(ans)); 25 scanf("%d",&T); 26 for(TT=1;TT<=T;TT++) 27 { 28 scanf("%d%d%d",&a,&b,&k); 29 if(k>82) 30 { 31 printf("Case %d: %d ",TT,0); 32 continue; 33 } 34 printf("Case %d: %d ",TT,get(b)-get(a-1)); 35 } 36 return 0; 37 }