|
3 | 3 |
|
4 | 4 | // combinatorics, dp |
5 | 5 | class Solution { |
| 6 | +public: |
| 7 | + int count(string num1, string num2, int min_sum, int max_sum) { |
| 8 | + static const int MOD = 1e9 + 7; |
| 9 | + const auto& check = [&](const auto& x) { |
| 10 | + const auto& total = accumulate(cbegin(x), cend(x), 0, [](const auto& accu, const auto& c) { |
| 11 | + return accu + (c - '0'); |
| 12 | + }); |
| 13 | + return min_sum <= total && total <= max_sum; |
| 14 | + }; |
| 15 | + |
| 16 | + const auto& f = [&](const auto& x) { |
| 17 | + vector<vector<int>> dp(2, vector<int>(max_sum + 1)); |
| 18 | + dp[0][0] = dp[1][0] = 1; |
| 19 | + for (int i = size(x) - 1; i >= 0; --i) { |
| 20 | + vector<vector<int>> new_dp(2, vector<int>(max_sum + 1)); |
| 21 | + for (int t = 0; t < 2; ++t) { |
| 22 | + for (int total = 0; total <= max_sum; ++total) { |
| 23 | + for (int d = 0; d <= min((t == 1 ? x[i] - '0' : 9), total); ++d) { |
| 24 | + new_dp[t][total] = (new_dp[t][total] + dp[static_cast<int>(t && d == x[i] - '0')][total - d]) % MOD; |
| 25 | + } |
| 26 | + } |
| 27 | + } |
| 28 | + dp = move(new_dp); |
| 29 | + } |
| 30 | + int result = 0; |
| 31 | + for (int total = min_sum; total <= max_sum; ++total) { |
| 32 | + result = (result + dp[1][total]) % MOD; |
| 33 | + } |
| 34 | + return result; |
| 35 | + }; |
| 36 | + |
| 37 | + return (((f(num2) - f(num1)) % MOD + MOD) % MOD + check(num1)) % MOD; |
| 38 | + } |
| 39 | +}; |
| 40 | + |
| 41 | +// Time: O(n * m), m = max_sum |
| 42 | +// Space: O(m) |
| 43 | +// combinatorics, dp |
| 44 | +class Solution2 { |
6 | 45 | public: |
7 | 46 | int count(string num1, string num2, int min_sum, int max_sum) { |
8 | 47 | static const int MOD = 1e9 + 7; |
|
0 commit comments