BUPT2017 wintertraining(15) #6C

题意

给长度n的数列,1,2,..,n,按依次递增递减排序,求字典序第k小的排列。

题解

dp。

up[i][j]表示长度为j,以第i小开头前两个递增的排列有几种。

down[i][j]表示长度为j,以第i小开头前两个递减的排列有几种。

那么有\(down[i][j]=\sum_{k=1}^{k=j-1}up[k][j-1]\)

并且有\(down[1][1]=1\),\(up[i][j]=down[j-i+1][j]\)。

然后就可以递推了。

求第k小的排列,令s[i]=i(i=1,2,…n),再令i为n到1,从小到大枚举未用过的i个数中第v小的,如果down[v][i]不比k小,说明后面是以第v小开头的长为i的开头递减排列,之后就要找这些排列中第k-down小的了。或判断up,根据标记的fup(表示之前是上升否)。输出s[v],并移除s[v]。

代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <iostream>
#define N 21
#define ll long long
using namespace std;
int t,n;
ll k;
ll up[N][N],down[N][N];
int s[N];
void get(){
int fup,v=0;
for(int i=1;i<=n;i++)s[i]=i;
for(int i=n;i;i--){//剩下i个位置要放
if(i==n){
for(int j=1;j<=n;j++){//放第1小到第n小
if(k<=down[j][i]){//先考虑下降,因为下降则这个方案更小
v=j;fup=0;break;//s[j]开头的够算,且是之后一个是上升
}
k-=down[j][i];//不够算,则找后面的第k-down大的方案。
if(k<=up[j][i]){
v=j;fup=1;break;
}
k-=up[j][i];
}
}else{
if(fup){
for(int j=v;j<=i;j++){
if(k<=down[j][i]){
v=j;break;
}
k-=down[j][i];
}
}else{
for(int j=1;j<v;j++){
if(k<=up[j][i]){
v=j;break;
}
k-=up[j][i];
}
}
fup^=1;
}
printf("%d ",s[v]);
for(int j=v;j<i;j++)s[j]=s[j+1];
}
puts("");
}
int main() {
down[1][1]=1;
for(int i=1;i<N;i++){
for(int j=2;j<=i;j++)
down[j][i]=down[j-1][i]+up[j-1][i-1];
//以第j小开头长度i的下降=sum_{k=1}^{k=j-1}{up[k][i-1]}
//那么down[j][i]-down[j-1][i]=up[j-1][i-1]
for(int j=1;j<=i;j++)
up[j][i]=down[i-j+1][i];
//第j小开头的上升=第i-j+1大开头的下降
}
scanf("%d",&t);
while(t--){
scanf("%d%lld",&n,&k);
get();
}
return 0;
}

【POJ1037】A decorative fence(DP)的更多相关文章

  1. 【BZOJ4712】洪水(动态dp)

    [BZOJ4712]洪水(动态dp) 题面 BZOJ 然而是权限题QwQ,所以粘过来算了. Description 小A走到一个山脚下,准备给自己造一个小屋.这时候,小A的朋友(op,又叫管理员)打开 ...

  2. 【BZOJ3387】[Usaco2004 Dec]Fence Obstacle Course栅栏行动 线段树

    [BZOJ3387][Usaco2004 Dec]Fence Obstacle Course栅栏行动 Description 约翰建造了N(1≤N≤50000)个栅栏来与牛同乐.第i个栅栏的z坐标为[ ...

  3. 【CF484E】Sign on Fence(主席树)

    [CF484E]Sign on Fence(主席树) 题面 懒得贴CF了,你们自己都找得到 洛谷 题解 这不就是[TJOI&HEOI 排序]那题的套路吗... 二分一个答案,把大于答案的都变成 ...

  4. 【题解】Jury Compromise(链表+DP)

    [题解]Jury Compromise(链表+DP) 传送门 题目大意 给你\(n\le 200\)个元素,一个元素有两个特征值,\(c_i\)和\(d_i\),\(c,d \in [0,20]\), ...

  5. 【题解】Making The Grade(DP+结论)

    [题解]Making The Grade(DP+结论) VJ:Making the Grade HNOI-D2-T3 原题,禁赛三年. 或许是我做过的最简单的DP题了吧(一遍过是什么东西) 之前做过关 ...

  6. 【题解】NOIP2017逛公园(DP)

    [题解]NOIP2017逛公园(DP) 第一次交挂了27分...我是不是必将惨败了... 考虑这样一种做法,设\(d_i\)表示从该节点到n​节点的最短路径,\(dp(i,k)\)表示从\(i\)节点 ...

  7. 【题解】284E. Coin Troubles(dp+图论建模)

    [题解]284E. Coin Troubles(dp+图论建模) 题意就是要你跑一个完全背包,但是要求背包的方案中有个数相对大小的限制 考虑一个\(c_i<c_j\)的限制,就是一个\(c_i\ ...

  8. 【CF917D】Stranger Trees 树形DP+Prufer序列

    [CF917D]Stranger Trees 题意:给你一棵n个点的树,对于k=1...n,问你有多少有标号的n个点的树,与给出的树有恰好k条边相同? $n\le 100$ 题解:我们先考虑容斥,求出 ...

  9. 【CF840C】On the Bench DP

    [CF840C]On the Bench 题意:给你一个长度为n的数组{ai},定义一个1到n的排列是合法的,当且仅当对于$1\le i <n$,$a_i\times a_{i+1}$不是完全平 ...

随机推荐

  1. Glad to see you! CodeForces - 810D (交互+二分)

    This is an interactive problem. In the output section below you will see the information about flush ...

  2. pycharm设置pytest运行程序

  3. 解决jenkins运行磁盘满的问题

    解决jenkins运行磁盘满的问题 - ling811的专栏 - CSDN博客 https://blog.csdn.net/ling811/article/details/74991899 1.自动丢 ...

  4. TortoiseGit push免输密码

    (ฅ>ω<*ฅ) 噫又好了~ TortoiseGit push免输密码的方法 – 晨旭的博客~https://www.chenxublog.com/2016/03/04/tortoiseg ...

  5. PHP 高并发秒杀解决方案

    本文提供 PHP 高并发秒杀解决方案(附加三个案例说明(普通流程,使用文件锁,使用redis消息队列)) 1:(正常流程,不做任何高并发处理),代码如下: <?php $_mysqli = ne ...

  6. C#的修饰符

    C#的修饰符 废话少说,直接上总结: 一.在命名空间下: 类:默认修饰符为internal 接口:默认的修饰符为internal 结构体:默认的修饰符为internal 枚举:默认的修饰符为inter ...

  7. 2 Modals of necessity

    1 情况动词must 和词组have to, need to ,have got to 都表示必须做某事或者要求做某事. need to  have to  must have got to When ...

  8. [转帖]Nginx rewrite模块深入浅出详解

    Nginx rewrite模块深入浅出详解 https://www.cnblogs.com/beyang/p/7832460.html rewrite模块(ngx_http_rewrite_modul ...

  9. 查看端口占用cmd命令

    查看端口被占用的进程: 在任务管理器中结束进程:

  10. github 操作

    https://www.cnblogs.com/cxk1995/p/5800196.html 1在已有的GitHub账号下创建项目. 2将GitHub项目克隆到本地.  git clone https ...