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;
}

 

 
posted @ 2021-03-11 19:37  cono奇犽哒  阅读(59)  评论(0)    收藏  举报