题目描述:
给定一个整数 n
,计算所有小于等于 n
的非负整数中数字 1
出现的个数。
数据范围:
$0 \le n \le 10^9$
题解:
经典数位dp,但是需要统计价值,因此直接返回 $val$ 就行。
记忆无限制的,而且不需要记录前导零,因为前导零 $0$ 的存在不会影响到 $1$ 的个数。
代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| auto optimize_cpp_stdio = []() { std::ios::sync_with_stdio(false); std::cin.tie(nullptr); std::cout.tie(nullptr); return 0; }(); class Solution { public: const static int maxn = 1e5 + 10; const static int maxm = 1e5 + 10; const int INF = 0x3f3f3f3f; string s; int n; int dp[10][10]; int dfs(int step, int val, bool isLimit) { if (step == n) return val; if (!isLimit && dp[step][val] != -1) return dp[step][val]; int ans = 0; int up = isLimit ? s[step] - '0' : 9; for (int i = 0; i <= up; ++i) { ans += dfs(step + 1, val + (i == 1), isLimit && i == up); } if (!isLimit) dp[step][val] = ans; return ans; } int countDigitOne(int num) { s = to_string(num); n = s.length(); memset(dp, -1, sizeof(dp)); return dfs(0, 0, true); } };
|