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;
}
                    
                
                
            
        
浙公网安备 33010602011771号