P2602 [ZJOI2010]数字计数

 1 #include <bits/stdc++.h>
 2 #define ll long long
 3 #define re register
 4 using namespace std;
 5 
 6 template <typename T>void in(T &x) {
 7     x = 0; T f = 1; char ch = getchar();
 8     while(!isdigit(ch)) {if(ch == '-') f = -1; ch = getchar();}
 9     while( isdigit(ch)) {x = 10 * x + ch - 48; ch = getchar();}
10     x *= f;
11 }
12 
13 template <typename T>void out(T x) {
14     if(x < 0) x = -x,putchar('-');
15     if(x > 9) out(x/10);
16     putchar(x%10 + 48);
17 }
18 //---------------------------------------------------------
19 const int N = 20;
20 ll a,b;
21 ll f[N][N];
22 int num[N];
23 
24 ll dfs(int pos,int lead,int limit,int digit,int sum) {
25     if(pos == 0) return sum;//边界 
26     if(lead && !limit && f[pos][sum] != -1) return f[pos][sum];
27     //先导不为0 未受限 已算过 -> 返回 
28     ll res = 0;
29     int up = (limit == 1 ? num[pos] : 9);
30     //int up = 9; if(limit) up = num[pos];
31     for(int i = 0; i <= up; ++i) {
32         res += dfs(pos-1,lead|i,(i==up)&&(limit),digit,sum+((lead|i)&&(i==digit)));    
33     }
34     if(lead && (!limit)) f[pos][sum] = res;
35     return res;
36 }
37 
38 ll solve(ll x,int digit) {
39     int len = 0;
40     while(x) num[++len] = x%10,x/=10;//逆序存数; 
41     memset(f,-1,sizeof(f));
42     dfs(len,0,1,digit,0);
43 }
44 
45 int main() {
46     in(a); in(b);
47     for(int digit = 0; digit <= 9; ++digit) {
48         out(solve(b,digit) - solve(a-1,digit)); putchar(' ');
49     }
50     return 0;
51 } 
原文地址:https://www.cnblogs.com/mzg1805/p/10998920.html