• [数位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;
    }
    
  • 相关阅读:
    Freewriting23_Hunting job again.
    PYDay4基本数据类型、字符串、元组、列表、字典
    PYDay3初识python
    PYDay2linux基础\常用命令
    PYDay1洗剑
    ASP.NET 2.0中GridView无限层复杂表头的实现(datagrid大同小易,repeater就不必这样,直接有头模版布局就可以)
    JavaScript获取HTML DOM节点元素的方法的总结
    Asp.net中实现同一用户名不能同时登陆(转)
    在JS文件中写脚本几种常见的形式
    获取repeater中头模版中的控件时要加从controls[0]
  • 原文地址:https://www.cnblogs.com/AEMShana/p/13696446.html
Copyright © 2020-2023  润新知