zoukankan      html  css  js  c++  java
  • [Ahoi2009]self 同类分布

    题意:给出a,b,求出[a,b]中各位数字之和能整除原数的数的个数。

    这道题把上界状态编入方程中时空复杂度才能过

    算见注

    #include<cstdio>
    #include<algorithm>
    #define int long long
    using namespace std;
    
    int f[2][20][170][170],vis[2][20][170][170];
    int d[20],ld;
    int p,tim;//模数,即枚举的数字和;tim是时间戳
    
    int dp(int fl,int dg,int s,int md){
        if(dg==0)return s==0&&md==0;
        if(vis[fl][dg][s][md]==tim)return f[fl][dg][s][md];
        vis[fl][dg][s][md]=tim;
        int res=0;
        //由于是自更新,需要知道当前位的取值范围
        int l=max(0ll,s-(dg-1)*9), r=min(s,(fl?9:d[dg]));
        for(int i=l;i<=r;i++){
            res+=dp(fl|(i<d[dg]),dg-1,s-i,(md*10+i)%p);
        }
        return f[fl][dg][s][md]=res;
    }
    int calc(int m){
        ld=0;
        while(m)d[++ld]=m%10,m/=10;
        //reverse(d+1,d+ld+1);
        int res=0;
        for(p=1;p<=ld*9;p++){
            ++tim;
            res+=dp(0,ld,p,0);
        }
        return res;
    }
    
    signed main(){
        int a,b;
        scanf("%lld%lld",&a,&b);
        printf("%lld",calc(b)-calc(a-1));
        return 0;
    }
    /*
     * fl:0表示满上界,1表示未满
     * dg:首位。这里是颠倒的,即1是最高位
     * s:数字和;md:余数
     * 状态表示,当前的最高位是从低到高第dg位,且第1-dg位的数字和为s,
     * 第dg+1~ld位的余数为md的数的个数
     */
    
    
  • 相关阅读:
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    Python for Data Science
    软件工程实践总结
  • 原文地址:https://www.cnblogs.com/sshwy/p/10995777.html
Copyright © 2011-2022 走看看