1049 Counting Ones (30 分)(数位dp的记忆化搜索)
题目描述:
1049 Counting Ones (30 分)
The task is simple: given any positive integer N, you are supposed to count the total number of 1's in the decimal form of the integers from 1 to N. For example, given N being 12, there are five 1's in 1, 10, 11, and 12.
Input Specification:
Each input file contains one test case which gives the positive N (≤).
Output Specification:
For each test case, print the number of 1's in one line.
Sample Input:
12
Sample Output:
5
思路:直接用数位dp模板没搞出来,换成记忆化搜索板子就过了...
#include<iostream> #include<queue> #include<string.h> #include<string> #include<map> #include<unordered_map> #include<vector> #include<algorithm> #include<cmath> #include<set> using namespace std; const int maxn = 100 + 1; const int maxm = 100 + 1; #define INT_MAX 0x7777777 typedef long long ll; inline int read() { int X = 0; bool flag = 1; char ch = getchar(); while (ch < '0' || ch>'9') { if (ch == '-') flag = 0; ch = getchar(); } while (ch >= '0' && ch <= '9') { X = (X << 1) + (X << 3) + ch - '0'; ch = getchar(); } if (flag) return X; return ~(X - 1); } int n; int dp[30][10]; int dfs(int pos, int ismax, int num) { if (!ismax && dp[pos][num]) { return dp[pos][num]; } if (pos == 0)return num; int h = ismax ? dig[pos] : 9; int ans = 0; for (int i = 0; i <= h; i++) { if (i == 1)ans += dfs(pos - 1, ismax & i == h, num+1); else ans += dfs(pos - 1, ismax & i == h, num); } dp[pos][num] = ans; return ans; } int dig[maxn]; int solve(int n) { int len = 0; while (n) { dig[++len] = n % 10; n /= 10; }dig[len + 1] = 0; return dfs(len, 1, 0); } int main() { int n; cout << solve(n)<< endl; return 0; }