|
| 1 | +package class085; |
| 2 | + |
| 3 | +// 统计整数数目 |
| 4 | +// 给你两个数字字符串 num1 和 num2 ,以及两个整数max_sum和min_sum |
| 5 | +// 如果一个整数 x 满足以下条件,我们称它是一个好整数 |
| 6 | +// num1 <= x <= num2 |
| 7 | +// min_sum <= digit_sum(x) <= max_sum |
| 8 | +// 请你返回好整数的数目 |
| 9 | +// 答案可能很大请返回答案对10^9 + 7 取余后的结果 |
| 10 | +// 注意,digit_sum(x)表示x各位数字之和 |
| 11 | +// 测试链接 : https://leetcode.cn/problems/count-of-integers/ |
| 12 | +public class Code01_CountOfIntegers { |
| 13 | + |
| 14 | + public static int MOD = 1000000007; |
| 15 | + |
| 16 | + public static int MAXN = 23; |
| 17 | + |
| 18 | + public static int MAXM = 401; |
| 19 | + |
| 20 | + public static int[][][] dp = new int[MAXN][MAXM][2]; |
| 21 | + |
| 22 | + public static void build() { |
| 23 | + for (int i = 0; i < n; i++) { |
| 24 | + for (int j = 0; j <= m; j++) { |
| 25 | + dp[i][j][0] = -1; |
| 26 | + dp[i][j][1] = -1; |
| 27 | + } |
| 28 | + } |
| 29 | + } |
| 30 | + |
| 31 | + public static char[] num; |
| 32 | + |
| 33 | + public static int n, m; |
| 34 | + |
| 35 | + public static int count(String num1, String num2, int min_sum, int max_sum) { |
| 36 | + num = num2.toCharArray(); |
| 37 | + n = num2.length(); |
| 38 | + m = max_sum; |
| 39 | + build(); |
| 40 | + int ans = f(0, 0, 0, min_sum, max_sum); |
| 41 | + num = num1.toCharArray(); |
| 42 | + n = num1.length(); |
| 43 | + build(); |
| 44 | + ans = (ans - f(0, 0, 0, min_sum, max_sum) + MOD) % MOD; |
| 45 | + if (check(min_sum, max_sum)) { |
| 46 | + ans = (ans + 1) % MOD; |
| 47 | + } |
| 48 | + return ans; |
| 49 | + } |
| 50 | + |
| 51 | + public static int f(int i, int sum, int less, int min, int max) { |
| 52 | + if (sum > max) { |
| 53 | + return 0; |
| 54 | + } |
| 55 | + if (sum + (n - i) * 9 < min) { |
| 56 | + return 0; |
| 57 | + } |
| 58 | + if (i == n) { |
| 59 | + return 1; |
| 60 | + } |
| 61 | + if (dp[i][sum][less] != -1) { |
| 62 | + return dp[i][sum][less]; |
| 63 | + } |
| 64 | + int cur = num[i] - '0'; |
| 65 | + int ans = 0; |
| 66 | + if (less == 0) { |
| 67 | + for (int pick = 0; pick < cur; pick++) { |
| 68 | + ans = (ans + f(i + 1, sum + pick, 1, min, max)) % MOD; |
| 69 | + } |
| 70 | + ans = (ans + f(i + 1, sum + cur, 0, min, max)) % MOD; |
| 71 | + } else { |
| 72 | + for (int pick = 0; pick <= 9; pick++) { |
| 73 | + ans = (ans + f(i + 1, sum + pick, 1, min, max)) % MOD; |
| 74 | + } |
| 75 | + } |
| 76 | + dp[i][sum][less] = ans; |
| 77 | + return ans; |
| 78 | + } |
| 79 | + |
| 80 | + public static boolean check(int min, int max) { |
| 81 | + int sum = 0; |
| 82 | + for (char cha : num) { |
| 83 | + sum += cha - '0'; |
| 84 | + } |
| 85 | + return sum >= min && sum <= max; |
| 86 | + } |
| 87 | + |
| 88 | +} |
0 commit comments