题意:给你一个数n和t,问字母出现次数不超过t,第n小的16进制数是多少。

思路:容易联想到数位DP, 然而并不是。。。我们需要知道有多少位,在知道有多少位之后,用试填法找出答案。我们设dp[i][j]为考虑前i种字母,已经占了j个位置的方案数。那么dp[i][j] += dp[i - 1][j - k] * C[len - j + k][k],k的范围为[0, limit[k]]。意思是我们暴力枚举第i个字母放多少个,然后排列组合。

这个题有一个细节需要注意,因为最高为一定不为0,所以我们试填的时候可以直接把最高位为0的所有数提前减掉,然后试填的时候跳过最高位为0的情况。最高位为0的所有数在找多少位的时候顺便就算出来了。

代码:

  1. #include <bits/stdc++.h>
  2. #define LL long long
  3. using namespace std;
  4. int limit[20];
  5. LL C[20][20], dp[20][20];
  6. void out(int x) {
  7. if(x < 10) printf("%d", x);
  8. else printf("%c", x - 10 + 'a');
  9. }
  10. LL solve(int len, int flag) {
  11. if(len == 0) return 1;
  12. memset(dp, 0, sizeof(dp));
  13. for (int i = 0; i <= len && i <= limit[0]; i++)
  14. dp[0][i] = C[len][i];
  15. for (int i = 1; i < 16; i++)
  16. for (int j = 0; j <= len; j++) {
  17. for (int k = 0; k <= j && k <= limit[i]; k++) {
  18. dp[i][j] += dp[i - 1][j - k] * C[len - j + k][k];
  19. }
  20. }
  21. return dp[15][len];
  22. }
  23. int res[20];
  24. int main() {
  25. LL n, ans;
  26. int m;
  27. scanf("%lld%d", &n, &m);
  28. ans = n;
  29. for (int i = 0; i < 16; i++) limit[i] = m;
  30. for (int i = 0; i <= 15; i++) C[i][0] = 1;
  31. for (int i = 1; i <= 15; i++)
  32. for (int j = 1; j <= i; j++)
  33. C[i][j] = C[i - 1][j - 1] + C[i - 1][j];
  34. int pos = -1;
  35. for (int i = 0; i >= 0; i++) {
  36. LL tmp = 0;
  37. for (int j = 1; j < 16; j++) {
  38. limit[j]--;
  39. tmp += solve(i, j);
  40. limit[j]++;
  41. if(tmp >= ans) {
  42. pos = i;
  43. break;
  44. }
  45. }
  46. if(tmp >= ans) break;
  47. else ans -= tmp;
  48. }
  49. n = ans;
  50. for (int i = pos; i >= 0 ; i--) {
  51. for (int j = 0; j < 16; j++) {
  52. if(i == pos && j == 0) continue;
  53. if(limit[j] == 0) continue;
  54. limit[j]--;
  55. LL tmp = solve(i, j);
  56. limit[j]++;
  57. if(tmp < n) {
  58. n -= tmp;
  59. } else {
  60. res[i] = j;
  61. limit[j]--;
  62. break;
  63. }
  64. }
  65. }
  66. for (int i = pos; i >= 0; i--) {
  67. out(res[i]);
  68. }
  69. printf("\n");
  70. }

  

Codeforces 747F Igor and Interesting Numbers DP 组合数的更多相关文章

  1. F. Igor and Interesting Numbers

    http://codeforces.com/contest/747/problem/F cf #387 div2 problem f 非常好的一道题.看完题,然后就不知道怎么做,感觉是dp,但是不知道 ...

  2. CF747F Igor and Interesting Numbers

    我佛了,这CF居然没有官方题解. 题意:给定k,t,求第k小的16进制数,满足每个数码的出现次数不超过t. 解: 每个数都有个出现次数限制,搞不倒.一开始想到了排序hash数位DP,不过写了写觉得不胜 ...

  3. 算法笔记_093:蓝桥杯练习 Problem S4: Interesting Numbers 加强版(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 Problem Description We call a number interesting, if and only if: 1. Its d ...

  4. java实现 蓝桥杯 算法提高 Problem S4: Interesting Numbers 加强版

    1 问题描述 Problem Description We call a number interesting, if and only if: 1. Its digits consists of o ...

  5. ural 2070. Interesting Numbers

    2070. Interesting Numbers Time limit: 2.0 secondMemory limit: 64 MB Nikolay and Asya investigate int ...

  6. Codeforces 385C Bear and Prime Numbers

    题目链接:Codeforces 385C Bear and Prime Numbers 这题告诉我仅仅有询问没有更新通常是不用线段树的.或者说还有比线段树更简单的方法. 用一个sum数组记录前n项和, ...

  7. Codeforces 1109D. Sasha and Interesting Fact from Graph Theory

    Codeforces 1109D. Sasha and Interesting Fact from Graph Theory 解题思路: 这题我根本不会做,是周指导带飞我. 首先对于当前已经有 \(m ...

  8. HDOJ(HDU).1058 Humble Numbers (DP)

    HDOJ(HDU).1058 Humble Numbers (DP) 点我挑战题目 题意分析 水 代码总览 /* Title:HDOJ.1058 Author:pengwill Date:2017-2 ...

  9. noj 2033 一页书的书 [ dp + 组合数 ]

    传送门 一页书的书 时间限制(普通/Java) : 1000 MS/ 3000 MS          运行内存限制 : 65536 KByte总提交 : 53            测试通过 : 1 ...

随机推荐

  1. Mac 电脑如何卸载 重装node

    由于在日常开发中,部分node版本不支持,因此,我们需要对已安装的node进行卸载重装,步骤如下: 一.在终端依次输入以下命令   sudo npm uninstall npm -g   sudo r ...

  2. C# Aspose.Words 数据写入到word,模板样式复杂(转换指定内容并返回多张图片)

    public ResultResponse<string[]> PrintStudyRecords([FromBody]StudyInfo info) { ResultResponse&l ...

  3. 2018-2-13-win10-uwp-绑定密码

    title author date CreateTime categories win10 uwp 绑定密码 lindexi 2018-2-13 17:23:3 +0800 2018-2-13 17: ...

  4. java一个数组的内存图

  5. js 输入整数

    1.我用 /^\+?[1-9][0-9]*$/ 貌似不对(小数也可以输入) 2.输入整数  n = /^[1-9]\d*$/; . -]\d*$/; //判断字符串是否为数字 if (!value) ...

  6. 解决分布式事务基本思想Base和CPA理论、最终一致性|刚性事务、柔性事务

    在学习解决分布式事务基本思路之前,大家要熟悉一些基本解决分布式事务概念名词比如:CAP与Base理论.柔性事务与刚性事务.理解最终一致性思想,JTA+XA.两阶段与三阶段提交等. 如何保证强一致性呢? ...

  7. MariaDB 建立连接

    与MariaDB建立连接的一种方法是在命令提示符下使用mysql二进制文件. MySQL脚本 查看下面给出的示例. [root@host]# mysql -u root -p Enter passwo ...

  8. 微信小程序点击顶部导航栏切换样式

    类似这样的效果 <view class='helpCateList'> <!-- 类别 --> <scroll-view class='scroll-view' scro ...

  9. hdu 3974 Assign the task (线段树+树的遍历)

    Description There is a company that has N employees(numbered from 1 to N),every employee in the comp ...

  10. 第七周-scrum meeting

    第一部分ScrumMeeting 每个人的工作:其他人:(请填写自己的任务) 成员 任务 ISSUE链接 本周已完成的工作 本周计划完成的工作 工作中遇到的困难 关玉娇 负责登录注册界面的设计与实现 ...