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的数的个数
     */
    
    
  • 相关阅读:
    高性能无锁队列,代码注释
    阿里mysql同步工具otter的docker镜像
    webgl鱼眼算法
    国际网络环境对库的影响
    newlisp
    java面试之数据库
    java面试之遇到过的问题
    java面试之springboot
    git常用命令
    java面试之jenkins
  • 原文地址:https://www.cnblogs.com/sshwy/p/10995777.html
Copyright © 2011-2022 走看看