zoukankan      html  css  js  c++  java
  • CF747F Igor and Interesting Numbers

    我佛了,这CF居然没有官方题解。

    题意:给定k,t,求第k小的16进制数,满足每个数码的出现次数不超过t。

    解:

    每个数都有个出现次数限制,搞不倒。一开始想到了排序hash数位DP,不过写了写觉得不胜其烦,就弃疗了。

    但是思考一下,如果我们知道了每个数的出现次数和数的位数,那么一次普通DP就能够求出方案数。

    所以我们暴力做多次这种普通DP即可......

    具体来说,分为带前导0和不带前导0两个DP函数。

    首先枚举数的长度,计算不带前导0的个数。如果不到k就减去。

    然后知道了长度,再一位一位的确定。在每一位上枚举放哪个数码。如果方案数不足就减去这么多。

    对于那个DP函数,状态设计f[i][j]表示用前i个数码放j位的数的方案数。转移就是

    f[i][j] = f[i - 1][j - k] * C(j, k),表示在j个位置中选出k个放数码i,剩下的放前面的数码,前面的数码相对位置不变。

     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 
     5 typedef long long LL;
     6 const int N = 200, B = 16;
     7 
     8 LL f[17][N], C[N][N], choose[N];
     9 int rest[B];
    10 
    11 inline LL DP(int n) { // with leading zero
    12     if(n <= 0) {
    13         return 1;
    14     }
    15     memset(f, 0, sizeof(f));
    16     for(int i = 1; i <= B; i++) {
    17         f[i - 1][0] = 1;
    18         for(int j = 1; j <= n; j++) {
    19             for(int k = 0; k <= rest[i - 1] && k <= j; k++) {
    20                 f[i][j] += f[i - 1][j - k] * C[j][k];
    21             }
    22         }
    23     }
    24 
    25     return f[16][n];
    26 }
    27 
    28 inline LL DP1(int n) { // no leading zero
    29     LL ans = 0;
    30     for(int i = 1; i < B; i++) {
    31         if(rest[i]) {
    32             rest[i]--;
    33             ans += DP(n - 1);
    34             rest[i]++;
    35         }
    36     }
    37     return ans;
    38 }
    39 
    40 int main() {
    41     for(int i = 1; i < 200; i++) {
    42         C[i][0] = C[i][i] = 1;
    43         for(int j = 1; j < i; j++) {
    44             C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
    45         }
    46     }
    47     int t;
    48     LL k;
    49     scanf("%lld%d", &k, &t);
    50     int len;
    51     for(len = 1; ; len++) {
    52         for(int i = 0; i < B; i++) {
    53             rest[i] = t;
    54         }
    55         LL temp = DP1(len);
    56         if(temp >= k) {
    57             break;
    58         }
    59         k -= temp;
    60     }
    61 
    62     for(int i = 0; i < B; i++) {
    63         rest[i] = t;
    64     }
    65     for(int i = len; i >= 1; i--) {
    66         for(int j = (i == len); j < B; j++) {
    67             if(!rest[j]) {
    68                 continue;
    69             }
    70             rest[j]--;
    71             LL temp = DP(i - 1);
    72             if(temp < k) {
    73                 k -= temp;
    74                 rest[j]++;
    75             }
    76             else {
    77                 choose[i] = j;
    78                 break;
    79             }
    80         }
    81     }
    82 
    83     for(int i = len; i >= 1; i--) {
    84         if(choose[i] < 10) {
    85             printf("%d", choose[i]);
    86         }
    87         else {
    88             putchar('a' + choose[i] - 10);
    89         }
    90     }
    91     return 0;
    92 }
    AC代码
  • 相关阅读:
    jQuery的deferred对象详解 jquery回调函数
    Table does not have the identity property. Cannot perform SET operation.
    SQLServer中merge函数用法详解
    jQuery事件命名空间多事件绑定自定义事件js 命名空间 javascript命名空间
    you have mixed tabs and spaces fix this
    java.lang.NoClassDefFoundError: javax/servlet/http/HttpServletRequest
    SQLServer 窗口函数
    TFS中查看我的所有签入迁出记录 TFS 怎么查看所有的修改
    日历控件My97DatePicker WdatePicker屏蔽 onchange的解决方法
    【Python】生成词云
  • 原文地址:https://www.cnblogs.com/huyufeifei/p/10206158.html
Copyright © 2011-2022 走看看