题目链接

这道题与下一章的数位\(dp\)解题思路十分一致。

把寻找答案变成按位(并且是字典序从小到大)枚举当前这一位可以填的情况。

通过\(dp\)预处理的信息告诉我们可行性,就可以把答案紧逼到一个更小的(子)问题,非常有趣。

考虑 \(dp\) 预处理的信息:

\(f[i][j][0 / 1]\) 表示 \(i\) 块木板,最左边的长度是第 \(j\) 小(排名为 \(j\) ),最左边这块是低位 / 高位的方案数。

由于木板的数量进行了变化,在加入一块新的木板后,木板的值域从 \([1, i - 1]\) 变成了 \([1, i]\),所以我们可以考虑把木板的长度变为一个相对的数量,从而进行转化。

考虑第一种转移

\(f[i][j][0] = \sum_{k = j}^{i - 1}f[i - 1][k][1]\)

可以看做是把后面 \(i - 1\) 块木板中真实长度 \(>= j\) 的再抬高一格,这样再拼一个 \(j\) 的木板就是一个合适的状态。

第二种转移也类似:

\(f[i][j][1] = \sum_{k = 1}^{j - 1} f[i - 1][k][0]\)

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
const int N = 21;
typedef long long LL;
int n;
bool st[N];
LL C, f[N][N][2];
void init() {
f[1][1][0] = f[1][1][1] = 1;
for (int i = 2; i < N; i++) {
for (int j = 1; j <= i; j++) {
for (int k = j; k <= i - 1; k++) f[i][j][0] += f[i - 1][k][1];
for (int k = 1; k <= j - 1; k++) f[i][j][1] += f[i - 1][k][0];
}
}
}
int main() {
init();
int T; scanf("%d", &T);
while (T--) {
memset(st, false, sizeof st);
scanf("%d%lld", &n, &C);
int k, last;
for (int i = 1; i <= n; i++) {
if (f[n][i][1] >= C) { k = 1, st[last = i] = true; printf("%d ", i); break; }
else C -= f[n][i][1];
if (f[n][i][0] >= C) { k = 0, st[last = i] = true; printf("%d ", i); break; }
else C -= f[n][i][0];
}
for (int i = n - 1; i; i--) {
k = k ^ 1;
int d = 0;
for (int j = 1; j <= n; j++) {
if (st[j]) continue;
++d;
if ((k == 0 && j < last) || (k == 1 && j > last)) {
// 要满足 j < last
if (f[i][d][k] >= C) { st[last = j] = true; printf("%d ", j); break; }
else C -= f[i][d][k];
}
}
}
puts("");
}
return 0;
}

最新文章

  1. Git版本控制工具(一)----git的安装及创建版本库
  2. EPROCESS KPROCESS PEB
  3. python_如何快速安装第三方库?
  4. django模型系统(一)
  5. mysql将视图数据迁移到表中
  6. centos7磁盘挂载及取消
  7. ELK收集Nginx|Tomcat日志
  8. POP-OOP-SOP-COP-SOA-AOP
  9. 学习推荐-Redis学习手册
  10. Oracle中Clob类型处理解析 (转)
  11. LAMP环境搭建实现网站动静分离[转]
  12. 进入一个docker容器
  13. java 发架包
  14. 应用.NET控制台应用程序开发批量导入程序。
  15. 《找出1到正整数N中出现1的次数》
  16. Vue于React特性对比(二)
  17. 495. Implement Stack【easy】
  18. 20个最受欢迎的Linux命令(转)
  19. Android proguard代码混淆
  20. Office HPDeskjetD2468 打印机电源灯闪烁不停,打印机不工作怎么办

热门文章

  1. C/C++中内存对齐问题的一些理解(转)
  2. 01Java环境安装监测
  3. redhat-NFS服务的配置与应用
  4. CorelDRAW文件损坏的几种解决方法
  5. 如何卸载MathType 7?
  6. PDF文档工具:pdfFactory快照功能详解
  7. leetcode 108 和leetcode 109
  8. 【P4178】Tree——点分治
  9. C语言讲义——变量(variable)
  10. TeXstudio 2020显示行号(与之前的版本位置不太一样)