Problem:
MathJax.Hub.Config({ tex2jax: { inlineMath: [["$","$"], ["\\(","\\)"]], processEscapes: true }});

Problem E
Bringing Order to Disorder

A sequence of digits usually represents a number, but we may define an alternative interpretation. In this problem we define a new interpretation with the order relation $\prec$ among the digit sequences of the same length defined below.

Let $s$ be a sequence of $n$ digits, $d_1d_2 ... d_n$, where each $d_i$ $(1 \leq i \leq n)$ is one of 0, 1, ... , and 9. Let sum($s$), prod($s$), and int($s$) be as follows:

sum($s$) = $d_1 + d_2 + ... + d_n$

prod($s$) = $(d_1 + 1) \times (d_2 + 1) \times ... \times (d_n + 1)$

int($s$) = $d_1 \times 10^{n-1} + d_2 \times 10^{n-2} + ... + d_n \times 10^0$

int($s$) is the integer the digit sequence $s$ represents with normal decimal interpretation.

Let $s_1$ and $s_2$ be sequences of the same number of digits. Then $s_1 \prec s_2$ ($s_1$ is less than $s_2$) is satisfied if and only if one of the following conditions is satisfied.

sum($s_1$) $<$ sum($s_2$)

sum($s_1$) $=$ sum($s_2$) and prod($s_1$) $<$ prod($s_2$)

sum($s_1$) $=$ sum($s_2$), prod($s_1$) $=$ prod($s_2$), and int($s_1$) $<$ int($s_2$)

For 2-digit sequences, for instance, the following relations are satisfied.

$00 \prec 01 \prec 10 \prec 02 \prec 20 \prec 11 \prec 03 \prec 30 \prec 12 \prec 21 \prec ... \prec 89 \prec 98 \prec 99$

Your task is, given an $n$-digit sequence $s$, to count up the number of $n$-digit sequences that are less than $s$ in the order $\prec$ defined above.

Input

The input consists of a single test case in a line.

$d_1d_2 ... d_n$

$n$ is a positive integer at most 14. Each of $d_1, d_2, ...,$ and $d_n$ is a digit.

Output

Print the number of the $n$-digit sequences less than $d_1d_2 ... d_n$ in the order defined above.

Sample Input 1

20

Sample Output 1

4

Sample Input 2

020

Sample Output 2

5

Sample Input 3

118

Sample Output 3

245

Sample Input 4

11111111111111

Sample Output 4

40073759

Sample Input 5

99777222222211

Sample Output 5

23733362467675

Solution in C++ (judge verdict: Accepted)

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <cassert>
#include <string>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
typedef long long LL;
const int N = 1005;

vector<LL> ver[15];
LL f[2][140][20000][2];

char str[20];

int main() {
    ver[0].push_back(1);
    for (int i = 0; i < 14; ++i) {
        for (int j = 0; j < ver[i].size(); ++j) {
            for (int k = 1; k <= 10; ++k)
                ver[i + 1].push_back(ver[i][j] * k);
        }
        sort(ver[i + 1].begin(), ver[i + 1].end());
        ver[i + 1].erase(unique(ver[i + 1].begin(), ver[i + 1].end()), ver[i + 1].end());
    }
    gets(str + 1);
    int n = strlen(str + 1);
    reverse(str + 1, str + 1 + n);
    int S = 0;
    LL P = 1;
    for (int i = 1; i <= n; ++i) {
        int tmp = str[i] - '0';
        S += tmp;
        P *= tmp + 1;
    }
    int cur = 0, nex = 1;
    f[cur][0][0][1] = 1;
    for (int i = 1; i <= n; ++i) {
        for (int j = 0; j <= S; ++j)
            for (int k = 0; k < ver[i].size(); ++k)
                for (int l = 0; l < 2; ++l)
                    f[nex][j][k][l] = 0;
        int ch = str[i] - '0';
        for (int j = 0; j <= S; ++j)
            for (int k = 0; k < ver[i - 1].size(); ++k)
                for (int l = 0; l < 2; ++l)
                    if (f[cur][j][k][l]) {
                        for (int p = 0; p < 10; ++p) {
                            if (j + p > S) continue;
                            int j1 = j + p;
                            int k1 = lower_bound(ver[i].begin(), ver[i].end(), ver[i - 1][k] * (p + 1)) - ver[i].begin();
                            int l1 = l;
                            if (p > ch) l1 = 1;
                            if (p < ch) l1 = 0;
                            f[nex][j1][k1][l1] += f[cur][j][k][l];
                        }
                    }
        swap(cur, nex);
    }
    LL ans = 0;
    for (int j = 0; j <= S; ++j)
        for (int k = 0; k < ver[n].size(); ++k)
            for (int l = 0; l < 2; ++l) {
                if (j != S) {
                    ans += f[cur][j][k][l];
                }
                else {
                    if (ver[n][k] != P) {
                        if (ver[n][k] < P) ans += f[cur][j][k][l];
                    }
                    else if (l == 0) ans += f[cur][j][k][l];
                }
            }
    cout << ans << endl;
}