• 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(崩溃)



     

  • 相关阅读:
    _status()函数
    _clear87()函数
    _clear87()函数
    _clear87()函数
    _clear87()函数
    南邮NOJ1009 2的n次方
    南邮NOJ2063 突发奇想的茂凯
    南邮NOJ2063 突发奇想的茂凯
    【HDOJ】1297 Children’s Queue
    【HDOJ】2103 Family planning
  • 原文地址:https://www.cnblogs.com/oldBook/p/13493472.html
Copyright © 2020-2023  润新知