• # 数位DP入坑


    Hdu 2089 不要62

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    typedef long long LL;
    
    inline int read()
    {
        char c=getchar();int num=0;
        for(;!isdigit(c);c=getchar());
        for(;isdigit(c);c=getchar())
            num=num*10+c-'0';
        return num;
    }
    
    const int N=1e6+5;
    
    int n,m;
    int a[20],dgt;
    int f[20][2;
    
    int dfs(int dep,int pre,int sta,bool lim)
    {
        if(!dep)
            return 1;
        if(!lim&&f[dep][sta!=-1)
            return f[dep][sta];
        int up=lim?a[dep]:9;
        int ans=0;
        for(int i=0;i<=up;++i)
        {
            if(i==4) continue;
            if(pre==6&&i==2) continue;
            ans+=dfs(dep-1,i,i==6,lim&&i==a[dep]);
        }
        if(!lim)
            f[dep][sta]=ans;
        return ans;
    }
    
    int solve(int x)
    {
        for(dgt=0;x;a[++dgt]=x%10,x/=10);
        return dfs(dgt,0,0,1);
    }
    
    int main()
    {
        while(1)
        {
            memset(f,-1,sizeof(f));
            n=read(),m=read();
            if(!n&&!m)
                break;
            cout<<solve(m)-solve(n-1)<<'
    ';
        }
        return 0;
    }
    View Code

    Hdu 6148 Valley Numer

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    typedef long long LL;
    
    inline int read()
    {
        char c=getchar();int num=0;
        for(;!isdigit(c);c=getchar());
        for(;isdigit(c);c=getchar())
            num=num*10+c-'0';
        return num;
    }
    
    const int N=105;
    const int mod=1e9+7;
    
    int T,n;
    char a[N];
    int f[N][10][3];
    
    int dfs(int dep,int pre,int turn,bool lim,bool invalid)
    {
        if(dep==n+1)
            return invalid?0:1;
        if(!lim&&f[dep][pre][turn]!=-1)
            return f[dep][pre][turn];
        int up=lim?a[dep]-='0':9;
        int ans=0;
        for(int i=0;i<=up;++i)
        {
            if(turn==2&&i<pre)
                continue;
            int p=0;
            if(invalid) p=0;
            else if(i>pre) p=2;
            else if(i<pre) p=1;
            else p=turn;
            ans+=dfs(dep+1,i,p,lim&&i==a[dep],invalid&&i==0);
            ans%=mod;
        }
        if(!lim)
            f[dep][pre][turn]=ans;
        return ans;
    }
    
    int main()
    {
        T=read();
        while(T--)
        {
            memset(f,-1,sizeof(f));
            scanf("%s",a+1);
            n=strlen(a+1);
            cout<<dfs(1,0,0,1,1)<<'
    ';
        }
        return 0;
    }
    View Code

    Bzoj 1026: [SCOI2009]windy数

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    typedef long long LL;
    
    inline LL read()
    {
        char c=getchar();LL num=0;
        for(;!isdigit(c);c=getchar());
        for(;isdigit(c);c=getchar())
            num=num*10+c-'0';
        return num;
    }
    
    LL A,B;
    LL a[100],dgt;
    LL f[100][10];
    
    LL dfs(int dep,int pre,bool lim,bool invalid)
    {
        if(!dep)
            return invalid?0:1;
        if(!lim&&!invalid&&f[dep][pre]!=-1)
            return f[dep][pre];
        int up=lim?a[dep]:9;
        LL ans=0;
        for(int i=0;i<=up;++i)
        {
            if(!invalid&&abs(i-pre)<2) continue;
            ans+=dfs(dep-1,i,lim&&i==a[dep],invalid&&i==0);
        }
        if(!lim&&!invalid)
            f[dep][pre]=ans;
        return ans;
    }
    
    LL solve(LL x)
    {
        for(dgt=0;x;a[++dgt]=x%10,x/=10);
        return dfs(dgt,0,1,1);
    }
    
    int main()
    {
        A=read(),B=read();
        memset(f,-1,sizeof(f));
        cout<<solve(B)-solve(A-1);
        return 0;
    }
    View Code

    Poj 3252  Round Numbers

    题意:问[l,r]中二进制位1比0少的数有多少个。

    Sol: 记录当前层0,1个数。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    typedef long long LL;
    
    inline int read()
    {
        char c=getchar();int num=0;
        for(;!isdigit(c);c=getchar());
        for(;isdigit(c);c=getchar())
            num=num*10+c-'0';
        return num;
    }
    
    int l,r;
    int a[65],bit;
    int f[65][65][65];
    
    int dfs(int dep,int c0,int c1,bool lim,bool invalid)
    {
        if(!dep)
            return (!invalid&&c0>=c1)?1:0;
        if(!lim&&f[dep][c0][c1]!=-1)
            return f[dep][c0][c1];
        int up=lim?a[dep]:1;
        int ans=0;
        for(int i=0;i<=up;++i)
            ans+=dfs(dep-1,c0+(i==0&&!invalid),c1+(i==1),lim&&i==up,invalid&&i==0);
        if(!lim)
            f[dep][c0][c1]=ans;
        return ans;
    }
    
    int solve(int x)
    {
        for(bit=0;x;a[++bit]=x&1,x>>=1);
        return dfs(bit,0,0,1,1);
    }
    
    int main()
    {
        memset(f,-1,sizeof(f));
        l=read(),r=read();
        cout<<solve(r)-solve(l-1);
        return 0;
    }
    View Code

    P2518 [HAOI2010]计数

    一个比较假的数位DP?但也是按照数位来做的。

    Sol:无。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    
    typedef long long LL;
    
    inline int read()
    {
        char c=getchar();int num=0;
        for(;!isdigit(c);c=getchar());
        for(;isdigit(c);c=getchar())
            num=num*10+c-'0';
        return num;
    }
    
    char num[61];
    LL ans;int n,m;
    int a[61],cnt[10];
    
    LL c[60][60];
    void init()
    {
        c[0][0]=1;
        for(int i=1;i<=50;++i)
        {
            c[i][0]=1;
            for(int j=1;j<=i;++j)
                c[i][j]=c[i-1][j-1]+c[i-1][j];
        }
    }
    
    LL C(int n)
    {
        LL res=1;
        for(int i=0;i<10;++i)
            if(cnt[i])
                res*=c[n][cnt[i]],n-=cnt[i];
        return res;
    }
    
    int main()
    {
        init();
        scanf("%s",num+1);
        for(n=1;num[n];++n)
            a[n]=num[n]-'0',++cnt[num[n]-'0'];
        m=--n;
        for(int i=1;i<=n;++i)
        {
            --m;
            for(int j=0;j<a[i];++j)
                if(cnt[j])
                    --cnt[j],ans+=C(m),++cnt[j];
            --cnt[a[i]];
        }
        cout<<ans;
        return 0;
    }
    View Code
  • 相关阅读:
    layui 获取select下拉选项上自定义的属性
    TP中关联模型的使用
    安卓模仿直播中的闪动(放大缩小)的动画
    Android报错Multiple dex files define Lcom/ta/utdid2/c/a/c
    Date.parse()的坑
    Android应用加固的简单实现方案(二)
    Android应用加固的简单实现方案
    Android中ANR的触发机制-BroadcastReceiver篇
    Android中ANR的触发机制-Service篇
    Application中以标准模式启动Activity报错的原因分析
  • 原文地址:https://www.cnblogs.com/lovewhy/p/9880069.html
Copyright © 2020-2023  润新知