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 排序的更多相关文章

  1. BZOJ 3990: [SDOI2015]排序 [搜索]

    3990: [SDOI2015]排序 题意:\(2^n\)的一个排列,给你n种操作,第i种把每\(2^{i-1}\)个数看成一段,交换任意两段.问是这个序列有序的操作方案数,两个操作序列不同,当且仅当 ...

  2. [BZOJ3990][SDOI2015]排序(DFS)

    3990: [SDOI2015]排序 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 902  Solved: 463[Submit][Status][ ...

  3. BZOJ 3990: [SDOI2015]排序(搜索+剪枝)

    [SDOI2015]排序 Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1< ...

  4. 【LG3322】[SDOI2015]排序

    [LG3322][SDOI2015]排序 题面 洛谷 题解 交换顺序显然不影响答案,所以每种本质不同的方案就给答案贡献次数的阶乘. 从小往大的交换每次至多\(4\)中决策,复杂度\(O(4^n)\). ...

  5. Bzoj3990 [SDOI2015]排序

    Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 651  Solved: 338 Description 小A有一个1-2^N的排列A[1..2^N], ...

  6. BZOJ3990:[SDOI2015]排序——题解

    https://www.lydsy.com/JudgeOnline/problem.php?id=3990 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作 ...

  7. [bzoj3990][SDOI2015]排序-搜索

    Brief Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1<=i<= ...

  8. BZOJ3990 [SDOI2015]排序 【搜索】

    题目 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1<=i<=N),第i中操作为将序列从左到 ...

  9. [sdoi2015]排序(搜索+剪枝优化)

    Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1<=i<=N),第i中 ...

随机推荐

  1. Spring详解------概述

    1.什么是 Spring ? Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One J2E ...

  2. ArcGIS图层添加字段出现:“定义了过多字段”

    首先,我图层数据格式为mdb,也就是Access数据库 Access一个表最大支持255个字段,可是我的才添加第一个字段就出现"定义了过多字段"的错误 打开ArcMap添加字段也是 ...

  3. Mybatis一对一、一对多、多对多查询。+MYSQL

    场景:使用三张数据表:student学生表.teacher教师表.position职位表 一个学生可以有多为老师.一位老师可以有多个学生.但是一个老师只能有一个职位:教授.副教授.讲师:但是一个职位可 ...

  4. 传统JIT和java9新特性AOT理解

    java慢的原因 1.  除了少量基本类型用栈存储外,所有对象都使用堆存储.堆的性能低于栈. 2.  很多强制类型转换(cast)或加查,耗用内存大.java运行时对类型检测,如果类型不正确会抛出Cl ...

  5. JAVA中的策略模式strategy

    原文出自:http://ttitfly.iteye.com/blog/136467 1. 以一个算术运算为例,传统做法为: java 代码 package org.common; public cla ...

  6. hdfs中数据迁移

    1.hdfs集群间数据迁移 hadoop distcp hdfs://192.128.112.66:8020/user/hive/warehouse/data.db/dwi_xxxx_d  /user ...

  7. Android Studio 百度地图导航

    配置就不再多说了,上一篇已经详细说过了,这次就是根据经纬度坐标做地图导航,路径规划.直接上代码: package com.example.appview.mian_page.Frament.Anzhu ...

  8. ffplay 播放网络摄像头视频

    shell脚本如下,无须加port ffplay rtsp://cameral_ip

  9. MySQL高可用主从复制新增slave

    原文转自:https://www.cnblogs.com/itzgr/p/10233932.html作者:木二 目录 一 基础环境 二 新增slave2方案 2.1 方案1:-复制主库 2.2 方案2 ...

  10. 搭建私服仓库:(一)Windows安装Nuxus

    Nexus下载 官网.官网下载.百度云盘 提取码:su33 将nexus下载下来,以2.14.5的windows版本为例子(3.x暂时下载不下来,迅雷会员都不行) 下载后进行解压,得到以下目录: 其中 ...