zoukankan      html  css  js  c++  java
  • CF55D Beautiful numbers 数位dp

    恢复魔芋本质,,改了1h+,,

    题目传送门

    其实这个题挺水的。也就我这种忘了%大佬的蒟蒻要调这么久。

    首先,我们要找的是能被每一位整除的数。处理成1~R的答案  -  1~(l-1)的答案。

    从最高位开始搜索放啥。如果已经是最后一位了,且当前数能被当前各位的最小公倍数整除,它就是一个合法的方案。那么,将长度,当前和,当前lcs,是否有限制带着搜就行了。

    注意,因为每一位只有1~9,这里的不同lcs最多不到50个,预处理离散化一下即可。

    还有就是本组数据结束的时候要把有限制的清空,无限制的保留(最早我全留着,果断挂得一分不剩),然后就是因为1~9的lcs为2520,所以每次的和对2520取模并无影响。然后,诶,又可以A了耶。

    #include<bits/stdc++.h>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<cstdlib>
    #include<algorithm>
    #include<queue>
    #include<deque>
    #include<list>
    #include<set>
    #include<vector>
    #include<iostream>
    #define ll long long
    #define re register
    #define inf 0x3f3f3f3f
    #define inl inline
    #define sqr(x) (x*x)
    //#define eps 1e-8
    #define debug printf("debug
    ");
    //#pragma comment(linker, "/STACK:1024000000,1024000000")
    //#pragma GCC optimize (2)
    //#pragma G++ optimize (2)
    using namespace std;
    const ll mod=2520;
    const ll MAXN=5e4+10;
    const ll MAXM=(5e4+10)*4;
    inl ll read() {
        re ll x = 0; re int f = 1;
        char ch = getchar();
        while(ch<'0'||ch>'9') { if(ch== '-' ) f = -1; ch = getchar(); }
        while(ch>='0'&&ch<='9') {x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
        return x * f;
    }
    inl char readc() {
        char ch=getchar();
        while(('z'<ch||ch<'a')&&('Z'<ch||ch<'A')) ch=getchar();
        return ch;
    }
    inl void write(re ll x){
        if(x>=10)write(x/10);
        putchar(x%10+'0');
    }
    inl void writeln(re ll x){
        if(x<0) {x=-x;putchar('-');}
        write(x); puts("");
    }
    inl ll gcd(re ll x,re ll y){while(y^=x^=y^=x%=y);return x;}
    inl ll Lcm(re ll a,re ll b) {return a/gcd(a,b)*b;}
    inl void FR() {
        freopen(".in","r",stdin);
        freopen(".out","w",stdout);
    }
    inl void FC() {
        fclose(stdin);
        fclose(stdout);
    }
    ll a[25],top,indx[5005],dp[25][5005][50];
    ll dfs(ll len,ll pre,ll lcm,bool limit) {
        if(!len) return (!(pre%lcm));
        if(!limit&&~dp[len][pre][indx[lcm]]) return dp[len][pre][indx[lcm]];
        ll num=limit?a[len]:9;
        ll ans=0;
        for(re ll i=0;i<=num;i++) {
            re ll nowsum,nowlcm=lcm;
            nowsum=((pre<<3)+(pre<<1)+i)%mod;
            if(i) nowlcm=Lcm(nowlcm,i);
            ans+=dfs(len-1,nowsum,nowlcm,limit&&i==num);
        }
        if(!limit) dp[len][pre][indx[lcm]]=ans;
        return ans;
    }
    ll calc(ll x) {
        top=0;
        while(x) {
            a[++top]=x%10;
            x/=10;
        }
        return dfs(top,0,1,1);
    }
    int main() {
    //  FR();
        re ll t=read();
        memset(dp,-1,sizeof(dp));
        for(re ll i=1,tot=0;i<=2520;i++) {
            if(!(mod%i)) indx[i]=++tot;
        }
        while(t--) {
            re ll l=read(),r=read();
            writeln(calc(r)-calc(l-1));
        }
    //  FC();
        return 0;
    }
    View Code
  • 相关阅读:
    第二阶段站立会议第十天
    第二阶段站立会议第九天
    第二阶段站立会议第八天
    第二阶段站立会议第七天
    第二阶段站立会议第六天
    第二阶段站立会议第五天
    第二阶段站立会议第四天
    第二冲刺阶段个人进度10
    第二冲刺阶段个人进度09
    第二冲刺阶段个人进度08
  • 原文地址:https://www.cnblogs.com/20020723YJX/p/9385898.html
Copyright © 2011-2022 走看看