http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2346
数位DP
代码:
#include <iostream> #include <cstdio> #include <string> #include <cstring> #include <cmath> #include <algorithm> #include <queue> #define ll long long using namespace std; int dp[11][90][10002]; int a[11]; int c[11]; int M; int dfs(int x,int k1,int k2,int flag) { if(x==-1) { if(k1==0&&k2==0) return 1; else return 0; } if(!flag&&dp[x][k1][k2]!=-1) return dp[x][k1][k2]; int up=(flag)?a[x]:9; int sum=0; for(int i=0;i<=up;++i) { //sum+=dfs(x-1,(k1+i)%M,(k2*10+i)%M,flag&&(i==up)); if(((k1-i)%M+M)%M<90)//两种递归,代表两种不同的含义,都是正确的 sum+=dfs(x-1,((k1-i)%M+M)%M,((k2-i*c[x])%M+M)%M,flag&&(i==up));
} if(!flag) dp[x][k1][k2]=sum; return sum; } int solve(int k) { int len=0; while(k) { a[len++]=k%10; k=k/10; } return dfs(len-1,0,0,1); } int main() { //freopen("data.in","r",stdin); int T; cin>>T; while(T--) { memset(dp,-1,sizeof(dp)); int a,b; cin>>a>>b>>M; c[0]=1; for(int i=1;i<=10;++i) c[i]=(c[i-1]*10)%M; //cout<<b<<" "<<solve(b)<<endl; cout<<solve(b)-solve(a-1)<<endl; } return 0; }