SDOI2015 排序
SDOI2015 排序
今天看到这道题,没有一点思路,暴力都没的打。。。还是理解错题意了,操作不同位置不是说改不同的区间,而是不同操作的顺序。。。考场上如果知道这个的话最少暴力拿一半啊,因为正解本来就是暴力。。
DFS
题目问的是方案数,如果操作确定了是谁的话顺序是无所谓的,压一个A(n n)加上就好。这一点很显然,不管怎么移动,如果先一后二可以,那么先二后一也是可以的。找规律就好。
现在需要做的是找到不同的操作序列,这里的不同不是指顺序,而是指种类。因为上面说了顺序无影响,那我们可以从最小的开始,能换就换,说白了就是暴搜%%%XIN队。
暴搜的话肯定要砍大树的,上面的思路如果大力搞的话必暴,其实在枚举序列找不满足递增顺序的区间时,如果区间数>2了,直接return。因为每种操作只有一次,一次肯定换不了两个以上的区间。如果没有不满足递增的区间,说明不需要这个操作,直接整一个DFS(x+1,num){x代表当前是第几个操作,num表示用了几个操作。}如果只有一个,那就自己换一下就OK。如果有两个,那么自己跟自己块里的两段肯定不能换,因为还有另一个块不合法,自己换了那人家怎么办。所以是2×2,枚举去换,换了后检查合法性如果合法就DFS(x+1,num+1)否则不用管。还有记得回溯的时候把换了的再给人换回去
。这样这道题就AC了。
不过苣蒻还是不懂玄学复杂度,明明是2^24,虽然远远达不到这个水平,但也不至于40ms就跑完了吧,一个点才2ms,这不是a+b的时间吗哈哈。
code有些冗长了,四种情况其实可以写函数的,我直接摆在那了,反正也是打一个然后复制粘贴,不过我好像改变量时少改了一个,调了好长时间。。算了,懒得改代码了,就这样吧。
#include<bits/stdc++.h>
using namespace std;
int n,a[1000101],ans=0;
inline void fr(){freopen("c.in","r",stdin);}
inline void sc(){scanf("%d",&n);}
namespace AYX
{ inline void dfs(int x,int num)
{ if(x==n+1)
{ int l=1;
for(int i=num;i;--i)
l*=i;
ans+=l;
return;
}
int len=(1<<(x)),kk=(1<<(x-1)),m1,m2,cnt=0;
for(int i=1;i<=(1<<n)-len+1;i+=len)
{ for(int j=i;j<(1<<x)/2+i;++j)
{ if(a[j]+kk!=a[j+kk])
{ ++cnt;
if(cnt==1)
m1=i;
else
m2=i;
break;
}
if(cnt>2)return;
}
}
if(cnt>2)return;
if(cnt==0)
{ dfs(x+1,num);
return ;
}
if(cnt==1)
{
for(int i=m1;i<=m1+kk-1;++i)
swap(a[i],a[i+kk]);
dfs(x+1,num+1);
for(int i=m1;i<=m1+kk-1;++i)
swap(a[i],a[i+kk]);
return;
}
bool bo=0;
int mm1=m1+kk,mm2=m2+kk;
for(int i=1;i<=kk;++i)
swap(a[i+m1-1],a[m2+i-1]);
for(int i=1;i<=kk;++i)
{ if(a[i+m1-1]+kk!=a[i+m1+kk-1] or a[i+m2-1]+kk!=a[i+m2+kk-1])
{
bo=1;break;
}
}
if(!bo)dfs(x+1,num+1);
for(int i=1;i<=kk;++i)
swap(a[i+m1-1],a[m2+i-1]);
bo=0;
for(int i=1;i<=kk;++i)
swap(a[i+mm1-1],a[m2+i-1]);
for(int i=1;i<=kk;++i)
{ if(a[i+m1-1]+kk!=a[i+m1+kk-1] or a[i+m2-1]+kk!=a[i+m2+kk-1])
{
bo=1;break;
}
}
if(!bo)dfs(x+1,num+1);
for(int i=1;i<=kk;++i)
swap(a[i+mm1-1],a[m2+i-1]);
bo=0;
for(int i=1;i<=kk;++i)
swap(a[i+m1-1],a[mm2+i-1]);
for(int i=1;i<=kk;++i)
{ if(a[i+m1-1]+kk!=a[i+m1+kk-1] or a[i+m2-1]+kk!=a[i+m2+kk-1])
{
bo=1;break;
}
}
if(!bo)dfs(x+1,num+1);
for(int i=1;i<=kk;++i)
swap(a[i+m1-1],a[mm2+i-1]);
bo=0;
for(int i=1;i<=kk;++i)
swap(a[i+mm1-1],a[mm2+i-1]);
for(int i=1;i<=kk;++i)
{ if(a[i+m1-1]+kk!=a[i+m1+kk-1] or a[i+m2-1]+kk!=a[i+m2+kk-1])
{
bo=1;break;
}
}
if(!bo)dfs(x+1,num+1);
for(int i=1;i<=kk;++i)
swap(a[i+mm1-1],a[mm2+i-1]);
}
inline void work()
{ for(int i=1;i<=(1<<n);++i)scanf("%d",&a[i]);
dfs(1,0);printf("%d\n",ans);
}
inline short main()
{sc();work();return 0;}
}
signed main()
{return AYX::main();}
SDOI2015 排序的更多相关文章
- BZOJ 3990: [SDOI2015]排序 [搜索]
3990: [SDOI2015]排序 题意:\(2^n\)的一个排列,给你n种操作,第i种把每\(2^{i-1}\)个数看成一段,交换任意两段.问是这个序列有序的操作方案数,两个操作序列不同,当且仅当 ...
- [BZOJ3990][SDOI2015]排序(DFS)
3990: [SDOI2015]排序 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 902 Solved: 463[Submit][Status][ ...
- BZOJ 3990: [SDOI2015]排序(搜索+剪枝)
[SDOI2015]排序 Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1< ...
- 【LG3322】[SDOI2015]排序
[LG3322][SDOI2015]排序 题面 洛谷 题解 交换顺序显然不影响答案,所以每种本质不同的方案就给答案贡献次数的阶乘. 从小往大的交换每次至多\(4\)中决策,复杂度\(O(4^n)\). ...
- Bzoj3990 [SDOI2015]排序
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 651 Solved: 338 Description 小A有一个1-2^N的排列A[1..2^N], ...
- BZOJ3990:[SDOI2015]排序——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3990 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作 ...
- [bzoj3990][SDOI2015]排序-搜索
Brief Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1<=i<= ...
- BZOJ3990 [SDOI2015]排序 【搜索】
题目 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1<=i<=N),第i中操作为将序列从左到 ...
- [sdoi2015]排序(搜索+剪枝优化)
Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1<=i<=N),第i中 ...
随机推荐
- 【转】ps命令详解与使用
ps 概述 Linux中的ps命令是Process Status的缩写.ps命令用来列出系统中当前运行的那些进程.ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,如果想要动态 ...
- (三)air202连接阿里云上传静态数据
具体步骤跳转–合宙官网 air202luat二次开发设备接入阿里云(一) air202luat二次开发设备接入阿里云(二) air202luat二次开发设备接入阿里云(三) 可能遇到的问题 群文件中有 ...
- Linux系统的vsftpd服务配置
概述: FTP ( 文件传输协议 ) 是 INTERNET 上仍常用的最老的网络协议之一 , 它为系统提供了通过网络与远程服务器进行传输的简单方法FTP 服务器包的名称为 VSFTPD , 它代表 V ...
- golang net/http包
http协议 超文本传输协议(HTTP,HyperText Transfer Protocol)是互联网上应用最为广泛的一种网络传输协议,所有的WWW文件都必须遵守这个标准.设计HTTP最初的目的是为 ...
- 开源的 Web 框架哪个快?我在 GitHub 找到了答案
在开源这片自由的土地上,孕育了太多开源 Web 框架.我在 GitHub 上搜了一下"web framework"关键字显示有 56000+ 匹配的开源项目,它们百花齐放各有特色, ...
- python代码检查工具(静态代码审查)
python静态代码检查 我们知道python是一门脚本语言,不像C#/Java等编译型语言可以在编译阶段就报出代码错误,脚本语言往往需要在运行期执行到这段代码时才会抛出代码错误. 那么在实际商业项目 ...
- Docker私有镜像仓库Harbor
一.安装Harbor(离线安装包的方式安装) 1.解压离线包 2.进入harbor目录中编辑harbor.yml 3.安装docker-compose yum -y install docker-co ...
- pluto中监听各个网口的500端口处理逻辑
1. pluto中监听各个网口的500端口处理逻辑 whack_handle() find_ifaces() find_raw_ifaces4() socket.setsockopt.bind.ioc ...
- QT之静态函数发送信号
一.简介 由于博主本人是初学者对QT的机制不了解,所以遇到了一个比较大的坑,特此记录一下.我遇到的问题是无法在静态函数中向另外一个类发送信号.解决办法:先将信号发送给同类中的普通函数,然后在从普通函数 ...
- python库--pandas--写入文本文件
pandas.DataFrame.to_csv 参数 说明 path_or_buf=None 文件路径或对象, 若果为None, 则结果作为字符串返回 sep=',' 分隔符 na_rep='' 缺失 ...