给你两个数字字符串 num1 和 num2 ,以及两个整数 max_sum 和 min_sum 。如果一个整数 x 满足以下条件,我们称它是一个好整数:
num1 <= x <= num2
min_sum <= digit_sum(x) <= max_sum.
请你返回好整数的数目。答案可能很大,请返回答案对 109 + 7 取余后>的结果。注意,digit_sum(x) 表示 x 各位数字之和。
class Solution {const int MOD = 1'000'000'007;int calc(string& s, int min_sum, int max_sum){int n = s.length();vector<vector<int>> memo(n, vector<int>(min(9*n, max_sum) + 1, -1));function<int(int, int, bool)> dfs = [&](int i, int sum, bool is_limit) -> int{if(sum > max_sum){return 0;}if(i == n){return sum >= min_sum ? 1 : 0;}if(! is_limit && memo[i][sum] != -1){return memo[i][sum];}int up = is_limit ? s[i] - '0' : 9;int res = 0;for(int d = 0; d <= up; d++){res = (res + dfs(i + 1, sum + d, is_limit &&d == up))% MOD;}if(!is_limit){memo[i][sum] = res;}return res;};return dfs(0, 0, true);}
public:int count(string num1, string num2, int min_sum, int max_sum) {int ans = calc(num2, min_sum, max_sum) - calc(num1, min_sum, max_sum) + MOD;int sum = 0;for(char x : num1){sum += x - '0';}ans += min_sum <= sum && sum <= max_sum;return ans % MOD;}
};
################################################
//之前写的一个通俗易懂的暴力 结果超时
class Solution {
public:int count(string num1, string num2, int min_sum, int max_sum) {int min_ = 0, max_ = 0;int num1_ = std::atoi(num1.c_str()), num2_ = std::atoi(num2.c_str());while(num1_ != 0){min_ = min_ *10 + num1_ % 10;num1_ /=10;}while(num2_ != 0){max_ = max_ *10 + num2_ % 10;num2_ /=10;}int ans = 0;for(int i = min_; i <= max_; ++i){int x = 0;while(i != 0){x += i % 10;i /= 10;}if(x >= min_sum && x <= max_sum){ans ++;}}//return (int)(ans%(1e9 + 7));return static_cast<int>(fmod(ans, 1e9 + 7));}
};
##############################################
后面继续详细分析数位这类题型 以及其核心思想