zoukankan      html  css  js  c++  java
  • LuoguP2602 [ZJOI2010]数字计数【数位dp】By cellur925

    题目传送门

    题目大意:给定两个正整数a和b,求在[a,b]中的所有整数中,每个数码(digit)各出现了多少次。


    继续数位dp=w=。

    这一次我们不需要记录$pre$啦!(撒花)。

    因为这次我们需要的是统计个数!那么我们就可以针对每个数字,搞一次记搜。记搜的时候只要注意传递下当前的数字个数就行了。

    当然了我们还是需要关注下前导0的,如果现在还是前导0呢,那么肯定不能计数了...

    Code

     1 #include<cstdio>
     2 #include<algorithm>
     3 #include<cstring>
     4 
     5 using namespace std;
     6 typedef long long ll;
     7 
     8 int len;
     9 int border[20];
    10 ll l,r;
    11 ll dp[20][20];
    12 
    13 ll dfs(int pos,int sum,int ling,int limit,int num)
    14 {
    15     if(pos<1) return sum;
    16     if(!limit&&dp[pos][sum]!=-1&&!ling) return dp[pos][sum];
    17     ll tmp=0;
    18     ll lim=limit ? border[pos] : 9;
    19     for(int i=0;i<=lim;i++)
    20     {
    21         if(ling&&i==0) tmp+=dfs(pos-1,0,1,limit&&i==lim,num);
    22         else tmp+=dfs(pos-1,sum+(i==num ? 1 : 0),0,limit&&i==lim,num);
    23     } 
    24     if(!ling&&!limit) dp[pos][sum]=tmp;
    25     return tmp;
    26 }
    27 
    28 ll work(ll x,int num)
    29 {
    30     len=0;
    31     memset(dp,-1,sizeof(dp));
    32     while(x)
    33     {
    34         border[++len]=x%10;
    35         x/=10;
    36     }
    37     return dfs(len,0,1,1,num);
    38 }
    39 
    40 int main()
    41 {
    42     scanf("%lld%lld",&l,&r);
    43     for(int i=0;i<=9;i++)
    44         printf("%lld ",work(r,i)-work(l-1,i));
    45     return 0;
    46 }
    View Code
  • 相关阅读:
    mysql备份还原
    JavaScript位移运算多个大于号的使用方法
    js with 语句的用法
    公告栏文字滚动
    Tar打包、压缩与解压缩到指定目录的方法
    域名跳转汇总文章
    linux常用命令大全
    nginx添加多站点
    linux一键安装php环境
    linux安装unzip及使用
  • 原文地址:https://www.cnblogs.com/nopartyfoucaodong/p/9788197.html
Copyright © 2011-2022 走看看