classSolution { public: intcountDigitOne(int n){ auto s = to_string(n); int m = s.size(), dp[m][m]; memset(dp, -1, sizeof(dp));
function<int(int, int, bool)>f = [&](int i, int cnt, bool isLimit) -> int { if (i == m) return cnt; if (!isLimit && dp[i][cnt] >= 0) return dp[i][cnt]; int res = 0; int up = isLimit ? s[i] - '0': 9; for (int d = 0; d <= up; d++) { res += f(i + 1, cnt + (d == 1), isLimit && d == up); } if (!isLimit) dp[i][cnt] = res; return res; }; returnf(0, 0, true);// 一开始需要限制 } };
classSolution { public: intcountSpecialNumbers(int n) { string s = to_string(n); int m = s.size(), dp[m][1<<m]; memset(dp, -1, sizeof(dp));
function<int(int, int, bool, bool)>f = [&](int i, int mask, int isLimit, int isNum) -> int { if (i == m) return isNum; if (!isLimit && isNum && dp[i][mask] != -1) return dp[i][mask]; int res = 0; if (!isNum) res = f(i + 1, mask, false, false); int up = isLimit ? s[i] - '0': 9; int low = isNum ? 1: 0; for (int d = low; d <= up; d++) { if ((mask>>d & 1) == 0) res += f(i + 1, mask | (1<<d), isLimit && up == d, true); } if (!isLimit && isNum) dp[i][mask] = res; return res; }; returnf(0, 0, true, false); } };