zoukankan      html  css  js  c++  java
  • [数位dp][洛谷P6371] [COCI2006-2007#6] V

    数位dp。
    (dp[pos][num]) 表示枚举到第 (pos) 位,并且前面的位数模 (X)(num) 时,使得最终能被 (X) 整除的数的个数。那么容易进行状态转移。

    但是发现 (X) 达到 (10^{11})(dp) 数组开不下,我们可以使用 map 来代替 (dp) 数组。但直接这样写将会 MLE 1个点。容易想到保存的无用的状态太多,很多情况答案都是为0的,我们考虑进行剪枝。

    设当前枚举到第 (pos) 位,并且前面的位数模 (X)(num) ,设 (temp=(X-num imes10^{pos}) mod X),设能使用的最大的数字为 (maxnum),那么若剩下的 (pos) 位数字全由 (maxnum) 组成,但仍比 (temp) 小,说明这样DFS下去必然不可能使得模数为0,直接剪枝即可。

    AC代码:

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    #include <string>
    #include <cstdio>
    #include <vector>
    #include <map>
    using namespace std;
    
    #define RG register int
    #define LL long long
    
    bool cnt[10];
    int a[20];
    LL Num[10][11],Ten[11];
    char str[20];
    map<LL,LL> dp[12];
    LL Div;
    int maxnum;
    
    LL DFS(int pos,bool limit,bool lead,LL num){
        if(!pos) return num==0?1:0;
        if(!limit && !lead && dp[pos].count(num)) return dp[pos][num];
        int up=limit?a[pos]:9;
        LL Res=0;
        LL temp=num*(Ten[pos]%Div)%Div,temp2;
        temp2=((Div-temp)%Div+Div)%Div;
        temp=Num[maxnum][pos];
        if(temp<temp2){
            if(!limit && !lead) dp[pos][num]=Res;
            return Res;
        }
        for(int i=0;i<=up;++i)
            if(cnt[i] || (i==0 && lead))
                Res+=DFS(pos-1,limit && i==up,lead && i==0,(num*10LL+i)%Div);
        if(!limit && !lead) dp[pos][num]=Res;
        return Res;
    }
    
    LL Solve(LL x){
        int pos=0;
        while(x){a[++pos]=x%10;x/=10;}
        return DFS(pos,true,true,0);
    }
    
    int main(){
        Ten[0]=1;
        for(RG i=1;i<11;++i)
            Ten[i]=Ten[i-1]*10LL;
        for(RG x=1;x<10;++x)
            for(RG i=1;i<11;++i)
                Num[x][i]=Num[x][i-1]*10LL+x;
        LL L,R;
        scanf("%lld%lld%lld",&Div,&L,&R);
        scanf("%s",str);
        int len=strlen(str);
        for(RG i=0;i<len;++i){
            cnt[str[i]-'0']=true;
            maxnum=max(maxnum,(int)(str[i]-'0'));
        }
        printf("%lld
    ",Solve(R)-Solve(L-1));
    
        return 0;
    }
    
  • 相关阅读:
    过滤器
    包装 request Demo
    分页思路
    导出数据库中所有数据到Excle中
    负载均衡集群中的session解决方案
    python 自动化之路 day 01 人生若只如初见
    python 自动化之路 day 00 目录
    切割TOMCAT日志
    Java进程CPU使用率高排查
    使用socket方式连接Nginx优化php-fpm性能
  • 原文地址:https://www.cnblogs.com/AEMShana/p/13696446.html
Copyright © 2011-2022 走看看