• 51nod 1042 数字0-9的数量 数位dp


    基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题
     收藏
     关注
    给出一段区间a-b,统计这个区间内0-9出现的次数。
     
    比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次。
    Input
    两个数a,b(1 <= a <= b <= 10^18)
    Output
    输出共10行,分别是0-9出现的次数
    Input示例
    10 19
    Output示例
    1
    11
    1
    1
    1
    1
    1
    1
    1
    1

    题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1042

    0的情况比较特殊,容易坑;

    #pragma comment(linker, "/STACK:1024000000,1024000000")
    #include<iostream>
    #include<cstdio>
    #include<cmath>
    #include<string>
    #include<queue>
    #include<algorithm>
    #include<stack>
    #include<cstring>
    #include<vector>
    #include<list>
    #include<set>
    #include<map>
    using namespace std;
    #define ll long long
    #define pi (4*atan(1.0))
    #define eps 1e-4
    #define bug(x)  cout<<"bug"<<x<<endl;
    const int N=3e3+10,M=1e6+10,inf=2147483647;
    const ll INF=1e18+10,mod=2147493647;
    ll f[30][100][100][16],bit[60];
    int k;
    ll dp(int pos,int pre,int sum,int xx,int kk,int flag,int q)
    {
        if(pos==0)return (sum==xx);
        if(flag&&f[pos][sum][xx][pre]!=-1)return f[pos][sum][xx][pre];
        int x=flag?9:bit[pos];
        ll ans=0;
        for(int i=0;i<=x;i++)
        {
            if(!q)
            {
                ///cout<<pos<<" "<<i<<endl;
                if(!i)ans+=dp(pos-1,i,sum,xx,kk,flag||i<x,q);
                else if(i==kk)ans+=dp(pos-1,i,sum+1,xx,kk,flag||i<x,1);
                else ans+=dp(pos-1,i,sum,xx,kk,flag||i<x,1);
            }
            else
            {
                ///cout<<"xxxx "<<i<<endl;
                if(i==kk)
                    ans+=dp(pos-1,i,sum+1,xx,kk,flag||i<x,1);
                else
                    ans+=dp(pos-1,i,sum,xx,kk,flag||i<x,1);
            }
        }
        if(flag)f[pos][sum][xx][pre]=ans;
        return ans;
    }
    ll getans(ll x,int k)
    {
        int len=0;
        while(x)
        {
            bit[++len]=x%10;
            x/=10;
        }
        ll ans=0;
        for(int i=1;i<=18;i++)
            ans+=dp(len,0,0,i,k,0,0)*i;
        return ans;
    }
    int main()
    {
    
        ll l,r;
        scanf("%lld%lld",&l,&r);
        for(k=0;k<=9;k++)
        {
            memset(f,-1,sizeof(f));
            printf("%lld
    ",getans(r,k)-getans(l-1,k));
        }
        return 0;
    }
    基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题
     收藏
     关注
    给出一段区间a-b,统计这个区间内0-9出现的次数。
     
    比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次。
    Input
    两个数a,b(1 <= a <= b <= 10^18)
    Output
    输出共10行,分别是0-9出现的次数
    Input示例
    10 19
    Output示例
    1
    11
    1
    1
    1
    1
    1
    1
    1
    1
  • 相关阅读:
    【mac】homebrew国内源安装加速
    【Mac】快速删除指定文件夹下的.DS_Store文件
    【mac】Mac微信小助手安装和卸载
    如何高效的开展app的性能测试
    什么是C#?什么是DOTNET?
    Xamarin Android使用自签名证书
    产品经理的私房菜
    java并发编程2-Synchronized关键字底层实现原理详解
    VS Code 1.60 发布!竟然可以自动检测编程语言了!
    为什么'x1B'.length===1?x与u知识延伸
  • 原文地址:https://www.cnblogs.com/jhz033/p/6601527.html
Copyright © 2020-2023  润新知