1. 程式人生 > 實用技巧 >1042 數字0-9的數量【解題數分DP】

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(崩潰)