Codeforces 55D 数位DP

来源:互联网 发布:lifemod软件下载 编辑:程序博客网 时间:2024/05/16 12:34
/*找出l到r内有多少个漂亮数漂亮数的定义是该数能被每个数位上的非零数字整除如250是漂亮数 250%2=250%5=0写出的bug1.注意返回dp值得调节是flag要为false2.下一个 状态的计算也错了。不应该写入是拆出的数位,应该是枚举的i*/#include <cstring>#include <cstdio>#include <algorithm>#include <cmath>#include <iostream>#include <set>using namespace std;#define ll long longint gcd(int a,int b){return b==0?a:gcd(b,a%b);}int id[6666];int last=0;int get(int a,int b){    return a/gcd(a,b)*b;}ll dp[20][2520][66];int q[666];int tail=0;ll dfs(int now,int mod,int lcm,bool flag){    if(now<0) return mod%lcm ==0;    if(!flag && dp[now][mod][id[lcm]] != -1) return dp[now][mod][id[lcm]];    int limit = flag?q[now]:9;    ll num=0;    for(int i=0;i<=limit;i++){        if(i!=0)            num += dfs(now-1, (mod*10+i)%2520, get(lcm,i), flag&&(i==limit));        else            num += dfs(now-1, mod*10%2520, lcm, flag&&(i==limit));    }    if(!flag) dp[now][mod][id[lcm]] = num;    return num;}ll W(ll x){    for(tail=0;x;x/=10){        q[tail++]=x%10;    }    return dfs(tail-1,0,1,true);}int main(){    //freopen("in.txt","r",stdin);    memset(dp,-1,sizeof(dp));    int t;    scanf("%d",&t);    set<int > ss;    for(int st=0;st<(1<<9);st++){        int LCM=1;        for(int i=0;i<9;i++){            if(st&(1<<i)) LCM=get(LCM,i+1);        }        ss.insert(LCM);    }    for(int x : ss){        id[x] = last++;    }    while(t--){        ll l,r;        scanf("%I64d%I64d",&l,&r);        //cout<<W(r)<<endl;        //cout<<W(l-1)<<endl;        printf("%I64d\n",W(r) - W(l-1));    }    return 0;}

0 0
原创粉丝点击