[Tkey] A decorative fence
还是看看简单而富有美感的爆搜吧
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define tests int cases;cin>>cases;while(cases--)
int n,l;
vector<int> e;bool vis[21];int cnt=0;
void dfs(int p){
if(cnt==l) return;
if(p>n){
cnt++;
if(cnt==l){
for(int i:e) cout<<i<<" ";
cout<<endl;
}
return;
}
for(int i=1;i<=n;++i){
if(!vis[i]){
if(e.size()<=1){
e.push_back(i);vis[i]=1;
dfs(p+1);
e.pop_back();vis[i]=0;
}
else if((*(e.end()-1)>*(e.end()-2)&&*(e.end()-1)>i)||
(*(e.end()-1)<*(e.end()-2)&&*(e.end()-1)<i)){
e.push_back(i);vis[i]=1;
dfs(p+1);
e.pop_back();vis[i]=0;
}
}
}
}
signed main(){
tests{
e.clear();cnt=0;
cin>>n>>l;
dfs(1);
}
}
思路
这题爆搜肯定是不行,考虑一个事实:
假设 1xxxx 是 \(Rank=a\) 的一种方案,1yyyy 是 \(Rank=b\) 的另一种方案,而目标 \(Rank\ k\) 满足 \(a\le k\le b\),则有 \(Rank=k\) 的方案的首位一定是 \(1\).
跟我们猜数是一样的. 假设有个数给你猜,\(114\) 小了,\(191\) 大了,那你肯定知道这个数最高位是什么了.
所以我们就开个数组来转移并维护这个 \(Rank\) 值.
注意到 \(Rank\) 并不是非常好维护,我们可以考虑维护每种情况的方案数,然后按字典序从小到大依次加起来,这样就是 \(Rank\) 值了.
设 \(f[i][j][k]\) 为放入前 \(i\) 块木板构成的栅栏,当第 \(i\) 块木板的 \(Rank=j\) 时的方案数. 注意到这样还是不好维护,因为要考虑是高低高还是低高低,那么再开一维 \(k\) 来表示这个. \(k=1\) 时 \(1\) 为高,反之亦然.
那么这个转移非常好写,也不是本题的难点.
\]
这里唯一需要注意的是求和的范围. 因为我们这个 \(k\) 指代的是 \(Rank=k\),而且会涉及到选高的还是选低的的问题,也就有了 \(k\) 的范围的差异.
那么还很容易注意到,这个转移和 \(n,m\) 完全没有关系,所以从多测里提出来作为初始化.
然后就是按上面的思想来逼近我们要求的答案.
先来确定第一位吧,我们需要做的就是遍历每个 \(1\le i\le n\),只要有 \(\sum^{i}_{j=1}(f[n][j][0]+f[n][j][1])> m\),就能判定 \(j-1\) 是我们要求的那个第一位.
很显然,当我们之前几位选过某个数字,那我们就不能再选了,因此在之后的几次逼近中,我们还需要判断当前 \(Rank\) 的板子是不是已经被使用过了,然后进行类似的判断即可.
#include<bits/stdc++.h>
using namespace std;
#define int long long
#define speed ios::sync_with_stdio(false);
#define tests int cases;cin>>cases;while(cases--)
#define clear(i) memset((i),0,sizeof (i))
int f[21][21][2]; //now fences have n planks, and the leftest planks ranking j
//k=0 means leftest is shorter,else taller
int n,m;
bool vis[21];
/*
f[i][j][1]=sum k{from 1 to j-1} f[i-1][k][0]
f[i][j][0]=sum k{from j to i-1} f[i-1][k][1]
*/
void prework(){
f[1][1][1]=1;f[1][1][0]=1;
for(int i=2;i<=20;++i){
for(int j=1;j<=i;++j){
for(int k=1;k<=j-1;++k){
f[i][j][1]+=f[i-1][k][0];
}
for(int k=j;k<=i-1;++k){
f[i][j][0]+=f[i-1][k][1];
}
}
}
}
signed main(){
prework();
speed tests{
cin>>n>>m;
clear(vis);
int now,last;
for(int i=1;i<=n;++i){
if(f[n][i][1]>=m){
last=i;now=1;break;
}
else{
m-=f[n][i][1];
}
if(f[n][i][0]>=m){
last=i;now=0;break;
}
else{
m-=f[n][i][0];
}
}
cout<<last<<" ";
vis[last]=true;
for(int i=2;i<=n;++i){
now=1-now;int rank=0;
for(int len=1;len<=n;++len){
if(vis[len]) continue;
rank++;
if((now==0 and len<last)or(now==1 and len>last)){
if(f[n-i+1][rank][now]>=m){
last=len;break;
}
else{
m-=f[n-i+1][rank][now];
}
}
}
vis[last]=true;
cout<<last<<" ";
}
cout<<endl;
}
}
[Tkey] 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 ...
- A decorative fence
A decorative fence 在\(1\sim n\)的全排列\(\{a_i\}\)中,只有大小交错的(即任意一个位置i满足\(a_{i-1}<a_i>a_{i+1}ora_{i- ...
- 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$块木板中从小到 ...
随机推荐
- DP进阶合集
(ps:本集合为Star_F总结的dp进阶知识,持续更新~. 转载本文章需要联系我,否则视为侵权!!) 前置知识:线性dp,背包,树形dp,区间dp 内容预览: 状压dp 数位dp dp优化(前缀和, ...
- 【Spring】02 过程分析
回顾JavaWeb三层架构设计: UserDao接口 public interface UserDao { void getUser(); } 实现类 public class UserDaoImpl ...
- 构建人工智能的工具 —— VXscan-R:数字孪生环境软件模块
地址: https://www.creaform3d.com.cn/zh/ji-liang-jie-jue-fang/vxscan-rshu-zi-luan-sheng-huan-jing-ruan- ...
- 再测python3.13a —— python3.13是否移除了GIL的限制(续)
前文: python3.13是否移除了GIL的限制 x86_64 ubuntu22.04环境下编译版本python3.13.0 alpha 0源码--python3.13.0 alpha 0的源码编译 ...
- 国产CPU(兆芯 kx-6640) 播放1080p视频效果
前一阵买了一个国产CPU的主机(国产CPU,国产操作系统UOS--零刻LZX迷你主机 , 显卡驱动安装以及屏幕配置),cpu是兆芯 kx-6640,用来播放1080p的视频虽然不是那么丝滑的流畅,但 ...
- 你要的高效方案!基于Apache SeaTunnel快速集成SAP进入Redshift
摘要 本文深入探讨了Apache SeaTunnel及其商业版可视化数据同步平台WhaleTunnel在数据整合领域的应用,特别是如何高效地将SAP系统中的数据同步到Amazon Redshift.通 ...
- FFmpeg开发笔记(四十五)使用SRT Streamer开启APP直播推流
SRT Streamer是一个安卓手机端的开源SRT协议直播推流框架,可用于RTMP直播和SRT直播.SRT Streamer支持的视频编码包括H264.H265等等,支持的音频编码包括AAC.OP ...
- 1. 从0开始学ARM-安装Keil MDK uVision集成开发环境
关于ARM的一些基本概念,大家可以参考我之前的文章: <到底什么是Cortex.ARMv8.arm架构.ARM指令集.soc?一文帮你梳理基础概念[科普]> 0. 如何学习arm? ARM ...
- Word格式刷快捷键失效恢复方法
突然某天写材料的时候发现word格式刷快捷键变成了Ctrl+Alt+C和Ctrl+Alt+V,用着这个别扭,于是探索如何改回Ctrl+Shift+C和Ctrl+Shift+V,下边是步骤记录. 打开w ...
- Echarts 5 动态按需引入图表
官网提供的按需引入方法为全量按需引入,在打包分离中,仍旧存在使用不到的图表被打包进去. 例如:组件A使用了折线图.柱状图,组件B只用到了折线图,但是打包组件B的时候,柱状图也就被打包进去. 本文提供一 ...