P3322 [SDOI2015]排序
HyperlinkHyperlinkHyperlink
https://www.luogu.com.cn/problem/P3322
DescriptionDescriptionDescription
有一个长度为2n2^n2n的序列,每次你可以选择任意两个长度为2k2^k2k的区间交换,求将序列变成有序的操作方案数
数据范围:n≤12n\leq 12n≤12
SolutionSolutionSolution
显然因为是交换操作,所以答案与操作顺序无瓜
由于操作都是2的进制弄的,我们从这个方面下手
首先我们把原序列拆分成2k2^k2k个小段,若所有小段都是有序的,则我们把相邻的两个小段合并在一起,也就是让k=k+1k=k+1k=k+1,此时没有进行操作
若有一个小段是无序的,则我们尝试让它的前半部分和后半部分交换
若交换后变成有序,则让k=k+1k=k+1k=k+1,此时进行了操作,dep=dep+1dep=dep+1dep=dep+1
否则剪枝
若有两个小段是无序的,则分四种情况,设这两段的编号p,qp,qp,q
- ppp的前半段和qqq的前半段交换
- ppp的前半段和qqq的后半段交换
- ppp的后半段和qqq的前半段交换
- ppp的后半段和qqq的后半段交换
若上述四种交换能有一种使得p,qp,qp,q这两段都变得有序,则k=k+1,dep=dep+1k=k+1,dep=dep+1k=k+1,dep=dep+1
否则剪枝
若有三段是无序的,直接剪掉
复杂度的上限是O(224)O(2^{24})O(224),然而实际运行中远远达不到
注意回朔
CodeCodeCode
#include<cstdio>
#include<algorithm>
#define jc puts("ok");
using namespace std;int pw[13]={1},n,A[5050],fac[13]={1},ans;
inline void SWAP(int p,int q,int k)
{for(register int i=0;i<pw[k];i++) swap(A[p+i],A[q+i]);return;
}
inline bool JUDGE(int p,int k)
{for(register int i=1;i<pw[k];i++) if(A[p+i]!=A[p+i-1]+1) return false;return true;
}
inline void dfs(int dep,int k)
{if(k>n) {ans+=fac[dep];return;}int p=0,q=0;for(register int i=1;i<=pw[n];i+=pw[k]){if(!JUDGE(i,k)){if(!p) p=i;else if(!q) q=i;}}if(p+q==0) dfs(dep,k+1);elseif(q==0){SWAP(p,p+pw[k-1],k-1);if(JUDGE(p,k)) dfs(dep+1,k+1);SWAP(p,p+pw[k-1],k-1);}elsefor(register int a=0;a<=pw[k-1];a+=pw[k-1])for(register int b=0;b<=pw[k-1];b+=pw[k-1]){SWAP(p+a,q+b,k-1);if(JUDGE(p,k)&&JUDGE(q,k)) {dfs(dep+1,k+1);SWAP(p+a,q+b,k-1);break;}SWAP(p+a,q+b,k-1);}
}
signed main()
{scanf("%d",&n);for(register int i=1;i<=n;i++) pw[i]=pw[i-1]<<1;for(register int i=1;i<=n;i++) fac[i]=fac[i-1]*i;for(register int i=1;i<=pw[n];i++) scanf("%d",A+i);dfs(0,0);printf("%d",ans);
}
P3322 [SDOI2015]排序相关推荐
- BZOJ 3990: [SDOI2015]排序(搜索+剪枝)
[SDOI2015]排序 Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1< ...
- SDOI2015 排序
Description 小A有一个1~2N的排列A[1..2N],他希望将数组A从小到大排序.小A可以执行的操作有N种,每种操作最多可以执行一次.对于所有的i(1<=i<=N),第i种操作 ...
- BZOJ.3990.[SDOI2015]排序(DFS)
题目链接 操作序列的顺序显然是无关的,所以只需按特定顺序求出一个长度为\(l\)的操作序列,它对答案的贡献为\(l!\). 我们从小到大枚举所有选择.若当前为第\(i\)个,如果有一段长度为\(2^i ...
- bzoj3990【SDOI2015】排序
3990: [SDOI2015]排序 Time Limit: 20 Sec Memory Limit: 128 MB Submit: 521 Solved: 271 [ Submit][ St ...
- [暑假的bzoj刷水记录]
(这篇我就不信有网站来扣) 这个暑假打算刷刷题啥的 但是写博客好累啊 堆一起算了 隔一段更新一下. 7月27号之前刷的的就不写了 , 写的累 代码不贴了,可以找我要啊.. 2017.8.27upd ...
- ZJOI2017 讲课Day1笔记
额,参考一下大神的笔记.... 地址 http://www.cnblogs.com/ARZhu-NOIpAK/p/6596879.html Day1 2017-3-24 3:34:43 苟-- 富贵 ...
- 退役前的做题记录1.0
退役前的做题记录1.0 租酥雨最近很懒qwq,具体表现在写题的时候不想发题解了. 但是想想这样也不太好,就决定发个一句话(半句话到几句话不等)题解上来. 2018-09.18-2018-09.28 [ ...
- 数据库中自定义排序规则,Mysql中自定义字段排序规则,Oracle中自定义字段排序规则,decode函数的用法,field函数的用法
数据库中自定义排序 场景:有一张banner表,表中有一个status字段,有0, 1, 2三个状态位,我想要 1,0,2的自定义排序(这里是重点),然后再进行之上对sequence字段进行二次排序( ...
- 伍六七带你学算法 进阶篇-排序算法
给定一个整数数组 nums,将该数组升序排列. 示例 1: 输入:[5,2,3,1] 输出:[1,2,3,5] 示例 2: 输入:[5,1,1,2,0,0] 输出:[0,0,1,1,2,5] 各排序算 ...
最新文章
- 大名鼎鼎的红黑树,你get了么?2-3树 绝对平衡 右旋转 左旋转 颜色反转
- 结对编程 黄金点游戏
- 技术部门Leader是不是一定要技术大牛担任?
- #绘制圆心_SolidWorks2018 绘制草图轮廓练习
- VC各种情况下的窗口句柄的获取
- 20210422:力扣第237周周赛题解记录(上)
- 电脑可以开机但是黑屏_铅锤哥:十五种电脑开机黑屏的原因与解决思路
- 三维点云学习(2)中-Kd-tree (k-dimensional tree)
- 文件标准标准IO与文件IO 的区别
- 【科普】你所不了解的SWF文件
- 杭州/北京内推 | 阿里达摩院招聘视觉生成方向学术实习生(人才计划)
- rxbus 源码_RxBus 这个 RxBus 稳如老狗 @codeKK Android开源站
- 菜鸟排版 latex + texstudio
- 论人工智能真空感应悬浮熔炼航母特种钢
- 港科百创| 香港科大-越秀集团百万奖金国际创业大赛·2021年度总决赛系列活动全回顾...
- 数据库选型-国产数据库如何满足你的需求
- php 基于gbk和 Ascii把汉字转换为拼音
- 备忘5:爬取微博热门信息以及所有热门微博评论的用户信息
- 使用HTML制作会员注册界面
- python在数学方面的应用_Python在小学数学应用中的可行性研究
热门文章
- 学习python-day01-13---转自Python分布式爬虫打造搜索引擎Scrapy精讲
- Camera ITS当中的test_lens_shading_and_color_uniformity测试
- Cubase10自编曲平台,享受音乐带来的快乐!
- Composer中的ThingWorx模型定义—建模
- C语言中lwr是谁的缩写,C语言中关于字符串的操作(转)
- 12个同父异母的孩子都有自闭症,简历造假的捐精者吸引了全球顶级专家
- JZYZOJ 1382 光棍组织 状压dp
- 春林文件批量改名系统
- win7批量修改计算机名,文件批量改名助手
- php文件更名,php如何批量给文件改名