数字计数(数位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\n",solve(r,9)-solve(l-1,9));
44     return 0;
45 }

 

posted @ 2020-11-30 20:21  swsyya  阅读(249)  评论(0编辑  收藏  举报

回到顶部