zoukankan      html  css  js  c++  java
  • bzoj1833: [ZJOI2010]count 数字计数 数位dp

    bzoj1833
    Description
    给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。
    Input
    输入文件中仅包含一行两个整数a、b,含义如上所述。
    Output
    输出文件中包含一行10个整数,分别表示0-9在[a,b]中出现了多少次。

    单独考虑每一位,数位dp,注意前导零

    /**************************************************************
        Problem: 1833
        User: walfy
        Language: C++
        Result: Accepted
        Time:72 ms
        Memory:1356 kb
    ****************************************************************/
     
    //#pragma comment(linker, "/stack:200000000")
    //#pragma GCC optimize("Ofast,no-stack-protector")
    //#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
    //#pragma GCC optimize("unroll-loops")
    #include<bits/stdc++.h>
    #define fi first
    #define se second
    #define mp make_pair
    #define pb push_back
    #define pi acos(-1.0)
    #define ll long long
    #define vi vector<int>
    #define mod 1000000007
    #define ld long double
    #define C 0.5772156649
    #define ls l,m,rt<<1
    #define rs m+1,r,rt<<1|1
    #define pil pair<int,ll>
    #define pli pair<ll,int>
    #define pii pair<int,int>
    #define cd complex<double>
    #define ull unsigned long long
    #define base 1000000000000000000
    #define fio ios::sync_with_stdio(false);cin.tie(0)
     
    using namespace std;
     
    const double eps=1e-6;
    const int N=20000+10,maxn=500000+10,inf=0x3f3f3f3f,INF=0x3f3f3f3f3f3f3f3f;
     
    int dight[20];
    ll dp[20][20][10][2];
    ll dfs(int id,int sum,int who,bool zero,int fp)
    {
        if(!id)
        {
            return sum;
        }
        if(!fp&&dp[id][sum][who][zero]!=-1)return dp[id][sum][who][zero];
        int fpmax=fp?dight[id]:9;
        ll ans=0;
        for(int i=0;i<=fpmax;i++)
        {
            if(i==who&&zero)ans+=dfs(id-1,sum+1,who,zero|i,fp&&i==fpmax);
            else ans+=dfs(id-1,sum,who,zero|i,fp&&i==fpmax);
        }
        if(!fp)dp[id][sum][who][zero]=ans;
        return ans;
    }
    ll ans[10];
    int main()
    {
        ll a,b;
        scanf("%lld%lld",&a,&b);
        memset(dp,-1,sizeof dp);
        int cnt=0;
        while(b)
        {
            dight[++cnt]=b%10;
            b/=10;
        }
        ans[0]+=dfs(cnt,0,0,0,1);
        for(int i=1;i<=9;i++)
            ans[i]+=dfs(cnt,0,i,1,1);
        a--;
        if(a>=1)
        {
            memset(dp,-1,sizeof dp);
            cnt=0;
            while(a)
            {
                dight[++cnt]=a%10;
                a/=10;
            }
            ans[0]-=dfs(cnt,0,0,0,1);
            for(int i=1;i<=9;i++)
                ans[i]-=dfs(cnt,0,i,1,1);
        }
        for(int i=0;i<9;i++)printf("%lld ",ans[i]);
        printf("%lld
    ",ans[9]);
        return 0;
    }
    /********************
     
    ********************/
    
  • 相关阅读:
    LeetCode 81 Search in Rotated Sorted Array II(循环有序数组中的查找问题)
    LeetCode 80 Remove Duplicates from Sorted Array II(移除数组中出现两次以上的元素)
    LeetCode 79 Word Search(单词查找)
    LeetCode 78 Subsets (所有子集)
    LeetCode 77 Combinations(排列组合)
    LeetCode 50 Pow(x, n) (实现幂运算)
    LeetCode 49 Group Anagrams(字符串分组)
    LeetCode 48 Rotate Image(2D图像旋转问题)
    LeetCode 47 Permutations II(全排列)
    LeetCode 46 Permutations(全排列问题)
  • 原文地址:https://www.cnblogs.com/acjiumeng/p/9292755.html
Copyright © 2011-2022 走看看