链接

这题规律其实挺明显的 打表找规律估计都可以 正规点就是DP

算出第N位所包含的good number的数量 如果给出的数是N+1位 就枚举各位上比原来小的数 加上下一位的dp值

一个i写成g了 纠结了半天。

hdu4722Good Numbers(dp)_g++hdu4722Good Numbers(dp)_#include_02
 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<stdlib.h>
 5 #include<algorithm>
 6 using namespace std;
 7 #define LL __int64
 8 LL dp[20][20],a,b,pp;
 9 void init()
10 {
11     int i,j,g;
12     for(i = 0 ; i <= 9 ; i++)
13     dp[1][i] = 1;
14     for(i = 2 ; i <= 18 ; i++)
15         for(j = 0 ; j < 10 ; j++)
16         for(g = 0 ; g <= 9 ; g++)
17         {
18             dp[i][(j+g)%10] += dp[i-1][j];
19         }
20 }
21 LL find(LL x)
22 {
23     int i,j,p[20],g=0;
24     while(x)
25     {
26         g++;
27         p[g] = x%10;
28         pp+=p[g];
29         x/=10;
30     }
31     int s=0;
32     LL ss=0;
33     for(i = g ; i >= 1 ; i--)
34     {
35         for(j = 0 ; j < p[i] ; j++)
36         {
37             int o = s+j;
38             if(i==1)
39             {
40                 if(o%10==0)
41                     ss+=1;
42                 continue;
43             }
44             for(int k = 0 ; k <= 9 ; k++)
45             {
46                 if((o+k)%10==0)
47                 ss+=dp[i-1][k];
48             }
49         }
50         s+=p[i];
51     }
52     return ss;
53 }
54 int main()
55 {
56     int t,i,kk=0;
57     init();
58     scanf("%d",&t);
59     while(t--)
60     {
61         kk++;
62         scanf("%I64d%I64d",&a,&b);
63         LL s1 = find(a);pp=0;
64         LL s2 = find(b);
65         if(pp%10==0)
66         s2++;
67         printf("Case #%d: ",kk);
68         printf("%I64d\n",s2-s1);
69     }
70     return 0;
71 }
View Code