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

      学习了一波记忆化数位dp后写这题...我好像写的都跟大家的不一样???跑的还挺快的???(其实全世界一样都是0ms...)

      题目大意:求[a,b]中0~9分别出现几次。(a,b<=10^12)

      dp[pos][num][sum]表示前pos位,求num出现几次,这个数前pos位num已经出现sum次,前导零也很好处理,套记忆化模板就行了。

      (太久没写博客了水一篇...(雾

    #include<iostream>
    #include<cstring>
    #include<cstdlib>
    #include<cstdio>
    #define ll long long
    using namespace std;
    ll dp[20][20][20],a[20],l,r;
    void read(ll &k)
    {
        k=0;ll f=1;char c=getchar();
        while(c>'9'||c<'0')c=='-'&&(f=-1),c=getchar();
        while(c<='9'&&c>='0')k=k*10+c-'0',c=getchar();
        k*=f;
    }
    ll dfs(int pos,int num,ll sum,bool lead,bool limit)
    {
        if(pos==0)return sum;
        if(!limit && !lead && dp[pos][num][sum]!=-1)return dp[pos][num][sum];
        int up=limit?a[pos]:9;
        ll ans=0;
        if(!lead||pos==1)ans+=dfs(pos-1,num,sum+(num==0),0,limit && a[pos]==0);
        else ans+=dfs(pos-1,num,sum,1,limit && a[pos]==0);
        for(int i=1;i<=up;i++)
        ans+=dfs(pos-1,num,sum+(num==i),0,limit && a[pos]==i);
        if(!limit && !lead)dp[pos][num][sum]=ans;
        return ans;
    }
    ll solve(ll x,int num)
    {
        if(x<0)return 0;
        if(x==0)return num==0?1:0;
        int pos=0;
        while(x)
        {
            a[++pos]=x%10;
            x/=10;
        }
        return dfs(pos,num,0,1,1);
    }
    int main()
    {
        read(l);read(r);
        memset(dp,-1,sizeof(dp));
        for(int i=0;i<=8;i++)
        printf("%lld ",solve(r,i)-solve(l-1,i));
        printf("%lld
    ",solve(r,9)-solve(l-1,9));
    }
    View Code
  • 相关阅读:
    hdu1290献给杭电五十周年校庆的礼物
    hdu1181(变形课)
    Flex结合java实现一个登录功能
    MyEclipse安装spket插件
    线程安全的理解
    很实用的一个ext表格,具有很好的分页功能。
    tomcat配置数据源
    extanychart柱状图呈现取自数据库中的数据
    extanychart饼图呈现取自数据库中的数据
    oracle实现分页总结
  • 原文地址:https://www.cnblogs.com/Sakits/p/6815468.html
Copyright © 2011-2022 走看看