Codeforces - 747F - Igor and engaging numbers DP + violence

Title Link

Question meaning: find the number of the smaller kkk from the hexadecimal numbers with no more than ttt occurrences of all numbers.

Idea: obviously, since the maximum number of kkk is no more than 2e9, the number of digits of this answer will not exceed 9. Then we can enumerate the number of hexadecimal digits under each digit to meet the requirements of the question, find the number of digits of the answer, and then enumerate from high to low.
The number of each length can be obtained violently. Set an array dp[i][j]dp[i][j]dp[i][j] DP [i] [J] to represent the number of jjj positions used for the first three numbers.

#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define PI acos(-1)
#define INF 0x3f3f3f3f
#define NUM 200010
#define debug true
#define lowbit(x) ((-x) & x)
#define ffor(i, d, u) for (int i = (d); i <= (u); ++i)
#define _ffor(i, u, d) for (int i = (u); i >= (d); --i)
#define mst(array, Num, Kind, Count) memset(array, Num, sizeof(Kind) * (Count))
const int P = 1e9 + 7;
template <typename T>
void read(T &x)
{
    x = 0;char c;T t = 1;
    while (((c = getchar()) < '0' || c > '9') && c != '-');
    if (c == '-'){t = -1;c = getchar();}
    do(x *= 10) += (c - '0');while ((c = getchar()) >= '0' && c <= '9');
    x *= t;
}
template <typename T>
void write(T x)
{
    int len = 0;char c[21];
    if (x < 0)putchar('-'), x *= (-1);
    do{++len;c[len] = (x % 10) + '0';} while (x /= 10);
    _ffor(i, len, 1) putchar(c[i]);
}
int t;
ll k, c[15][15];
ll dp[16][20];
int limit[16];
char num[16] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
ll check(const int &len)
{
    memset(dp, 0, sizeof(dp));
    ffor(i, 0, min(limit[0], len)) dp[0][i] = c[len][i];
    ffor(i, 1, 15)
        ffor(j, 0, len)
            ffor(z, 0, min(limit[i], j))
                dp[i][j] += (dp[i - 1][j - z] * c[len - j + z][z]);
    return dp[15][len];
}
void AC()
{
    read(k), read(t);
    c[0][0] = c[1][0] = c[1][1] = 1;
    ffor(i, 2, 14)
    {
        c[i][0] = c[i][i] = 1;
        ffor(j, 1, i - 1)
            c[i][j] = c[i - 1][j - 1] + c[i - 1][j];
    }
    ffor(i, 0, 15) limit[i] = t;
    int len = 1;
    ll ans;
    for (;; ++len)
    {
        ans = 0;
        if(len == 1)
            ans = 15;
        else
            ffor(i, 1, 15)
            {
                --limit[i], ans += check(len - 1);
                ++limit[i];
            }
        if (ans < k)
            k -= ans;
        else
            break;
    }
    _ffor(i, len, 1)
    {
        ffor(j, 0, 15)
        {
            if (i == len && j == 0)
                continue;
            if (limit[j] == 0)
                continue;
            --limit[j];
            if ((ans = check(i - 1)) >= k)
            {
                putchar(num[j]);
                break;
            }
            k -= ans, ++limit[j];
        }
    }
}
int main()
{
    AC();
    return 0;
}

Posted by horsefaceba on Wed, 20 Nov 2019 13:51:52 -0800