CF1277A. Happy Birthday, Polycarp! Enumeration problem solution / digital DP

Topic links: http://codeforces.com/contest/1277/problem/A

Title effect:
demand interval \ ([1, n] \ ) there is contained a number of how many numbers in a range.
For example: \ (1,77,777,44,999999 \) are contains only one digit number, and \ (12,11110,6969,987654321 \) these are not.

Outline of Solution:
This problem may be employed (the feeling of course, some digital DP relatively overkill) and digital enumeration DP solution to solve.

Enumeration Solution

First of all, we have to determine, remove \ (0 \) other than a \ (i \) digits at most \ (9 \) like this number:

  • \ (1 \) digits in total \ (9 \) a satisfactory number: \ (1,2,3,4,5,6,7,8,9 \) ;
  • \ (2 \) digits in total \ (9 \) a satisfactory number: \ (11,22,33,44,55,66,77,88,99 \) ;
  • \ (3 \) digits in total \ (9 \) a satisfactory number: \ (111,222,333,444,555,666,777,888,999 \) ;
  • ……

Because to tell us \ (1 \ the n-Le \ Le 10 ^ 9 \) , so we consider the most \ (9 \) digits can be.

In other words, the number of all meet the requirements only \ (9 \ times 9 = 81 \) months, we just need to enumerate this \ (81 \) number, and then determine how many \ (\ le n \) to .

Codes are as follows:

#include<bits/stdc++.h>
using namespace std;
int T, n;
int solve() {
    int cnt = 0;
    for (int i = 1; i <= 9; i ++) {
        int s = 0;
        for (int j = 0; j < 9; j ++) {
            s = s * 10 + i;
            if (s > n) break;
            cnt ++;
        }
    }
    return cnt;
}
int main() {
    cin >> T;
    while (T --) {
        cin >> n;
        cout << solve() << endl;
    }
    return 0;
}

DP Digital Solution

We define the state \ (f [pos] [pre ] \) indicates that when

  • Digits before the point where for the first \ (pos \) position,
  • A former element is placed \ (pre \) (if the former does not place any element of the \ (pre = 0 \) )

When the total number of programs.

And open function dfs(int pos, int pre, bool limit)for solving:

  • Before the point where the number of bits for the first \ (pos \) position;
  • A former element is placed \ (pre \) (if the former does not place any element of the \ (pre = 0 \) );
  • \ (limit \) for indicating whether the current idle transited

When the total number of programs.

But the final answer because it contains \ (0 \) in this program, so to minus \ (1 \) .

Codes are as follows:

#include<bits/stdc++.h>
using namespace std;
int f[11][11], T, n, a[11];
void init() {
    memset(f, -1, sizeof(f));
}
int dfs(int pos, int pre, bool limit) {
    if (pos < 0) return 1;
    if (!limit && f[pos][pre] != -1) return f[pos][pre];
    int up = limit ? a[pos] : 9;
    int tmp = 0;
    for (int i = 0; i <= up; i ++) {
        if (pre == 0) {
            if (i == 0) tmp += dfs(pos-1, i, limit && i==up);
            else tmp += dfs(pos-1, i, limit && i==up);
        }
        else if (i == pre) tmp += dfs(pos-1, i, limit && i==up);
    }
    if (!limit) f[pos][pre] = tmp;
    return tmp;
}
int get_num(int x) {
    int pos = 0;
    while (x) {
        a[pos++] = x%10;
        x /= 10;
    }
    return dfs(pos-1, 0, true);
}
int main() {
    init();
    cin >> T;
    while (T --) {
        cin >> n;
        cout << get_num(n)-1 << endl;
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/quanjun/p/12041358.html