[CF 747F]Igor and Interesting Numbers

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[CF 747F]Igor and Interesting Numbers相关的知识,希望对你有一定的参考价值。

题目大意:

给出整数k,t.需要从小到大产生第k个符合条件的十六进制数,使每一位上的数出现次数不超过t.

 

看到题时反正是一脸懵逼.

后来看了

我们用dp[i][l]表示用前i个数字,将数的空位填上l个的数有几个.

方程\(d{p_{i,l}} = \sum {d{p_{i - 1,l - j}} \times C_j^{len + j - l}} \)

 

代码如下:

 1 #include <cstdio>
 2 #include <cstring>
 3 #define N 198
 4 long long C[N][N],dp[16][N],k;int t,num[16];
 5 #define __min(a,b) (((a)<(b))?(a):(b))
 6 #define __max(a,b) (((a)>(b))?(a):(b))
 7 const char tohex[] = "0123456789abcdef";
 8 #define print(a) putchar(tohex[(a)])
 9 inline void pre()
10 {
11     for(int i = 0;i < N;i++) C[i][0] = 1;
12     for(int i = 1;i < N;i++) for(int j = 1;j <= i;j++) C[i][j] = C[i - 1][j] + C[i - 1][j - 1];
13 }
14 inline long long solve(int len)
15 {
16     memset(dp,0,sizeof(dp));
17     for(int i = 0;i <= num[0];i++) dp[0][i] = C[len][i];
18     for(int i = 1;i < 16;i++) for(int l = 0;l <= len;l++) for(int j = 0;j <= __min(num[i],l);j++) dp[i][l] += dp[i - 1][l - j] * C[len - l + j][j];
19     return dp[15][len];
20 }
21 int main()
22 {
23     pre();scanf("%lld %d",&k,&t);for(register int i = 0;i < 16;i++)num[i] = t;
24     register int len = 1;
25     for(;;len++)
26     {
27         long long tmp = 0;
28         if(len == 1)tmp = 15;
29         else for(register int j = 1;j < 16;j++)
30         {
31             num[j]--;
32             tmp += solve(len - 1);
33             num[j]++;
34         }
35         if(k > tmp) k -= tmp;
36         else break;
37     }
38     for(register int i = len; i > 0; i--)
39     {
40         if(i == 1)
41         {
42             for(register int j = 0; j < 16; j++)
43             {
44                 if(!j && len == 1) continue;
45                 if(num[j]) k--;
46                 if(!k){ print(j); break; }
47             }
48             break;
49         }
50         for(register int j = 0; j < 16; j++)
51         {
52             if(i == len && !j) continue;
53             num[j]--;
54             register long long tmp = solve(i - 1);
55             if(k > tmp) k -= tmp;else{print(j);break;}
56             num[j]++;
57         }
58     }
59     return 0;
60 }

 

以上是关于[CF 747F]Igor and Interesting Numbers的主要内容,如果未能解决你的问题,请参考以下文章

Codeforces 747F Igor and Interesting Numbers DP 组合数

codeforces 793B - Igor and his way to work(dfsbfs)

CS294-112 深度强化学习 秋季学期(伯克利)NO.19 Guest lecture: Igor Mordatch (Optimization and Reinforcement Learnin

Codeforces Round #387 (Div. 2) 747F(数位DP)

Igor绘制雷达图

(CF#257)B. Jzzhu and Sequences