1042 数字0-9的数量【解题数分DP】

题目

给出一段区间a-b,统计这个区间内0-9出现的次数。

比如 10-19,1出现11次(10,11,12,13,14,15,16,17,18,19,其中11包括2个1),其余数字各出现1次

输入

两个数a,b(1 <= a <= b <= 10^18)

输出

输出共10行,分别是0-9出现的次数

输入样例

10 19

输出样例

1
11
1
1
1
1
1
1
1
1

 代码

 1 import java.util.*;
 2 
 3 public class Main {
 4 
 5     static long a, b;
 6     static Scanner scan = new Scanner(System.in);
 7     static long[][][] f = new long[25][10][10];
 8 
 9     public static void init() {
10         for (int i = 0; i < 10; ++i) {
11             f[1][i][i] = 1;
12         }
13 
14         for (int i = 2; i < 25; ++i) {
15             for (int j = 0; j < 10; ++j) {
16                 for (int k = 0; k < 10; ++k) {
17                     if (j == k) {
18                         f[i][j][k] += (long) Math.pow(10, i - 1);
19                     }
20                     for (int p = 0; p < 10; ++p) {
21                         f[i][j][k] += f[i - 1][p][k];
22                     }
23                 }
24             }
25         }
26 
27     }
28 
29 
30     public static long[] dp(long n) {
31         long[] res = new long[10];
32         ArrayList<Integer> last = new ArrayList<Integer>();
33 
34         if (n == 0) {
35             res[0] += 1;
36             return res;
37         }
38 
39 
40         ArrayList<Integer> nums = new ArrayList<Integer>();
41         while (n > 0) {
42             nums.add((int) (n % 10));
43             n /= 10;
44         }
45 //
46 
47         for (int i = nums.size() - 1; i >= 0; --i) {
48             int x = nums.get(i);
49             if (i == nums.size() - 1) {
50                 for(int p=i;p>=0;--p){
51                     res[0]-=(long)Math.pow(10,p);
52                 }
53 //                res[0] -= (long) Math.pow(10, i);
54 //                res[0] -= (long) Math.pow(10, i);
55             }
56             for (int j = 0; j < x; ++j) {
57                 for (int p = 0; p < 10; ++p) {
58                     res[p] += f[i + 1][j][p];
59                 }
60                 for (int t : last) {
61                     res[t] += (long) Math.pow(10, i);
62                 }
63             }
64 
65             last.add(x);
66             if (i == 0) {
67                 for (int t : last) {
68                     res[t] += 1;
69                 }
70 
71             }
72         }
73         return res;
74 
75     }
76 
77     public static void main(String[] args) {
78         a = scan.nextLong();
79         b = scan.nextLong();
80 
81         init();
82         long[] res1 = dp(b);
83         long[] res2 = dp(a - 1);
84         for (int i = 0; i < 10; ++i) {
85             res1[i] -= res2[i];
86         }
87 
88         for (long t : res1) {
89             System.out.println(t);
90         }
91 
92 
93     }
94 
95 }

总结

关键是把dp搞对,然后注意细节部分,比如这道题中的前导0(崩溃)



 

原文地址:https://www.cnblogs.com/oldBook/p/13493472.html