A decorative fence
在\(1\sim n\)的全排列\(\{a_i\}\)中,只有大小交错的(即任意一个位置i满足\(a_{i-1}<a_i>a_{i+1}ora_{i-1}>a_i<a_{i+1}\))排列方案才是合法的,询问合法的第c个方案的全排列,\(n\leq 20,c\leq 2^{63}\)。
解
首先是求第几个方案,自然要用试填法,而排列问题不同于普通递推,因为一个数被放在这一个位置就不能在放了,但是注意到排列的一个性质,也就是注重大小关系,故可以考虑离散化递推。
为了试填,自然表现最左端填什么,也要表现序列的长度,为了能够维护序列的合法,不妨把最左端\(a_i>a_{i+1}\)记做,否则记做0,所以设\(f[i][j][k]\)表示长度为i的排列,最左端的数为第j大的数,状态为k的方案数,不难有
\]
\]
边界:\(f[1][1][0]=f[1][1][1]=1\),其余为0
于是我们就可以直接利用方案数从小到大试填了,注意第一个位置状态可1,可0,优先填1即可。
参考代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#define il inline
#define ri register
#define ll long long
using namespace std;
bool used[21];
ll dp[21][21][2];
il void prepare();
int main(){
	int lsy;scanf("%d",&lsy),prepare();
	while(lsy--){
		int n,last;bool p;ll c;
		memset(used,0,sizeof(used));
		scanf("%d%lld",&n,&c);
		for(int i(1);i<=n;++i){
			if(dp[n][i][1]>=c){
				last=i,p=1;
				break;
			}
			else c-=dp[n][i][1];
			if(dp[n][i][0]>=c){
				last=i,p=0;
				break;
			}
			else c-=dp[n][i][0];
		}printf("%d ",last),used[last]|=true;
		for(int i(2),j,k;i<=n;++i){
			p^=true;
			for(j=1,k=0;j<=n;++j){
				if(used[j])continue;++k;
				if((p&&j>last)||(!p&&j<last))
					if(dp[n-i+1][k][p]>=c){
						last=j,used[j]|=true;
						break;
					}
					else c-=dp[n-i+1][k][p];
			}printf("%d ",last);
		}putchar('\n');
	}
	return 0;
}
il void prepare(){
	dp[1][1][0]=dp[1][1][1]=1;
	for(int i(2),j,k;i<=20;++i)
		for(j=1;j<=i;++j){
			for(k=j;k<i;++k)dp[i][j][0]+=dp[i-1][k][1];
			for(k=1;k<j;++k)dp[i][j][1]+=dp[i-1][k][0];
		}
}
A decorative fence的更多相关文章
- POJ1037 A decorative fence
		题意 Language:Default A decorative fence Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 84 ... 
- POJ1037 A decorative fence 【动态规划】
		A decorative fence Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 6489 Accepted: 236 ... 
- poj 1037 A decorative fence
		题目链接:http://poj.org/problem?id=1037 Description Richard just finished building his new house. Now th ... 
- OpenJ_Bailian - 1037   A decorative fence
		Discription Richard just finished building his new house. Now the only thing the house misses is a c ... 
- POJ1037A decorative fence(动态规划+排序计数+好题)
		http://poj.org/problem?id=1037 题意:输入木棒的个数n,其中每个木棒长度等于对应的编号,把木棒按照波浪形排序,然后输出第c个; 分析:总数为i跟木棒中第k短的木棒 就等于 ... 
- POJ1037A decorative fence(好dp)
		1037 带点组合的东西吧 黑书P257 其实我没看懂它写的嘛玩意儿 这题还是挺不错的 一个模糊的思路可能会好想一些 就是大体的递推方程 dp1[][]表示降序 dp2[][]表示升序 数组的含义为长 ... 
- 【POJ1037】A decorative fence(DP)
		BUPT2017 wintertraining(15) #6C 题意 给长度n的数列,1,2,..,n,按依次递增递减排序,求字典序第k小的排列. 题解 dp. up[i][j]表示长度为j,以第i小 ... 
- poj1037 [CEOI 2002]A decorative fence 题解
		---恢复内容开始--- 题意: t组数据,每组数据给出n个木棒,长度由1到n,除了两端的木棒外,每一根木棒,要么比它左右的两根都长,要么比它左右的两根都短.即要求构成的排列为波浪型.对符合要求的排列 ... 
- $Poj1037\ A\ Decorative\ Fence$ 计数类$DP$
		Poj AcWing Description Sol 这题很数位$DP$啊, 预处理$+$试填法 $F[i][j][k]$表示用$i$块长度不同的木板,当前木板(第$i$块)在这$i$块木板中从小到 ... 
随机推荐
- 并发新构件之Semaphore:信号量
			Semaphore :JDK描述,通常用于限制可以访问某些资源(物理或逻辑的)的线程数目.一句话说明了他的作用.信号量有一个虚拟的许可证池,new Semaphore(10):构造一个含有10个许可证 ... 
- python实现马赛克拼图!
			python实现马赛克拼图 直接上代码! 代码如下: #!/usr/local/bin/python3# --*-- coding:utf8 --*-- import getoptimport sy ... 
- Samcompu Loves Water
			题目背景 Samcompu拥有大量的"水"资源!! 题目描述 Samcompu需要制定一个水计划.这个计划的主要目的就是为了避开老师监视的时间来水. 老师在中途会离开机房T次,第i ... 
- 209. Minimum Size Subarray Sum【滑动窗口】
			Given an array of n positive integers and a positive integer s, find the minimal length of a contigu ... 
- 软工-五月心得体会 PB16110698
			伴随着愈发红润的骄阳,火热而紧张刺激的五月悄然而至.这一个月以来,曾经让同学们“废寝忘食”的软工课大作业终于告一段落,每周一篇的读书笔记也缓到半月一篇,着实令人长吐一口气.但这一份表面的余裕当然没有看 ... 
- linux redis安装及JAVA使用jedis
			一.redis安装 1.安装redis 将redis安装包放到指定目录下.并用tar -zxvf redis.*****.tar.gz解压2.想把redis安装到哪里,就在哪里创建redis文件夹. ... 
- PushSharp 由于远程方已关闭传输流,身份验证失败。
			前段时间用到了PushSharp给APNS发推送,但是用的时候遇见很诡异的事情,每次第一次运行的时候能成功发送到 但是接下来就无限的提示“由于远程方已关闭传输流,身份验证失败. “ 然后我就各种找原因 ... 
- ThreadLocal知识点
			ThreadLocal是什么 ThreadLocal 表面上看他是和多线程,线程同步有关的一个工具类,但其实他与线程同步机制无关.线程同步机制是多个线程共享同一个变量,而ThreadLocal是为每个 ... 
- java内省Introspector
			大纲: JavaBean 规范 内省 一.JavaBean 规范 JavaBean —般需遵循以下规范. 实现 java.io.Serializable 接口. javaBean属性是具有getter ... 
- php面向对象深入理解(二)
			一个简单的小程序: 配置 config.ini <?php //项目的根目录 define("ROOT","F:/文件夹的名字/oop/"); //数 ... 
