luogu P6371 [COCI2006-2007#6] V 数位dp

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=15,maxx=100005;
int tmp[maxn],vis[10];
long long dp[maxn][maxx][2],X;
long long dfs(int pos,int mod,int _0,int up)
{
    if(pos==0)
        return _0==0&&mod==0;
    if(!up&&(~dp[pos][mod][_0]))
        return dp[pos][mod][_0];
    long long ans=0;
    int mx=up?tmp[pos]:9;
    for(int i=1; i<=mx; ++i)
        if(vis[i])
            ans+=dfs(pos-1,(mod*10+i)%X,_0&&i==0,up&&i==tmp[pos]);
    if(_0)
        ans+=dfs(pos-1,0,1,up&&tmp[pos]==0);
    else if(vis[0])
        ans+=dfs(pos-1,mod*10%X,false,up&&tmp[pos]==0);
    if(!up)
        dp[pos][mod][_0]=ans;
    return ans;
}
long long solve(long long test)
{
    int cnt=0;
    while(test)
    {
        tmp[++cnt]=test%10;
        test/=10;
    }
    return dfs(cnt,0,1,1);
}
int judge(long long test)
{
    while(test)
    {
        if(!vis[test%10])
            return false;
        test/=10;
    }
    return true;
}
int main()
{
    long long A,B;
    cin>>X>>A>>B;
    string s;
    cin>>s;
    for(int i=0; i<s.size(); i++)
        vis[s[i]-'0']=true;
    if(X<=maxx)
    {
        memset(dp,-1,sizeof dp);
        cout<<(solve(B)-solve(A-1))<<endl;
    }
    else
    {
        int l=(int)((A-1)/X+1),r=(int)(B/X),ans=0;
        for(int x=l; x<=r; ++x)
            if(judge(1ll*X*x))//直接枚举倍数
                ++ans;
        cout<<ans<<endl;
    }
    return 0;
}
原文地址:https://www.cnblogs.com/QingyuYYYYY/p/12934808.html