• 数字计数(数位dp)


    数字计数(数位dp)

    细节见代码:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 typedef long long ll;
     4 const int maxn = 20;
     5 const int mod = 1e9+7;
     6 
     7 ll l,r;
     8 int a[15];
     9 ll dp[15][10][15];//dp[pos][num][sum]:位pos 之前当前num字符已经出现sum次
    10 
    11 ll dfs(int pos,int num, ll sum, bool lead,bool limit){
    12 
    13     if( !pos ) return sum;
    14     if( !limit&&!lead&& dp[pos][num][sum]!=-1 ) return dp[pos][num][sum];
    15     int up = limit?a[pos]:9;
    16     ll ans=0;
    17 
    18     for(int i=0;i<=up;i++){
    19         if( i==0 ){
    20             if( !lead || pos==1 ) ans += dfs(pos-1,num,sum+(num==i),0,limit&&i==up);//此位的0非前导0
    21             else ans += dfs(pos-1,num,sum,1,limit&&i==up);//此位的0是前导0
    22         }else{
    23             ans += dfs(pos-1,num,sum+(num==i),0,limit&&(i==up));
    24         }
    25     }
    26     return ( (!limit)&&(!lead))?dp[pos][num][sum]=ans:ans;
    27 }
    28 
    29 ll solve(ll x,int num){
    30     a[0] = 0;
    31     if( !x ) return num==0?1:0;//注意这里
    32     while( x ) a[++a[0]]=x%10, x/=10;
    33     return dfs(a[0],num,0,1,1);
    34 }
    35 
    36 int main()
    37 {
    38     memset(dp,-1,sizeof(dp));
    39     scanf("%lld%lld",&l,&r);
    40     for(int i=0;i<=8;i++){
    41         printf("%lld ",solve(r,i)-solve(l-1,i));
    42     }
    43     printf("%lld
    ",solve(r,9)-solve(l-1,9));
    44     return 0;
    45 }
  • 相关阅读:
    数论-FTT 和 NTT
    数论-FFT高精度乘法
    树链剖分-模板题 HAOI2015
    图论-最小生成树模板
    图论-次短路求法
    图论-某图论专练 Round3 (April, 2018)
    动规-某动规专练 Round1 (April, 2018)
    动规-某动规专练 Round2 (April, 2018)
    Java IO: 并发IO
    Java IO: Reader And Writer
  • 原文地址:https://www.cnblogs.com/wsy107316/p/14063385.html
Copyright © 2020-2023  润新知