Description

小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1<=i<=N),第i中操作为将序列从左到右划分为2^{N-i+1}段,每段恰好包括2^{i-1}个数,然后整体交换其中两段.小A想知道可以将数组A从小到大排序的不同的操作序列有多少个,小A认为两个操作序列不同,当且仅当操作个数不同,或者至少一个操作不同(种类不同或者操作位置不同).

  下面是一个操作事例:
  N=3,A[1..8]=[3,6,1,2,7,8,5,4].
  第一次操作,执行第3种操作,交换A[1..4]和A[5..8],交换后的A[1..8]为[7,8,5,4,3,6,1,2].
  第二次操作,执行第1种操作,交换A[3]和A[5],交换后的A[1..8]为[7,8,3,4,5,6,1,2].
  第三次操作,执行第2中操作,交换A[1..2]和A[7..8],交换后的A[1..8]为[1,2,3,4,5,6,7,8].

Input

第一行,一个整数N

第二行,2^N个整数,A[1..2^N]

Output

一个整数表示答案

Sample Input

3
7 8 5 6 1 2 4 3

Sample Output

6

正解居然是搜索,考场上看这板儿B是个神仙状压就skip掉了

后悔啊……把猛肝某APIO2016T1的时间放这题上怎么还没30分啊……

手%几组数据可以发现,操作序列的合法性与顺序无瓜

所以只需确定序列中有没有第i种操作,最后将统计结果的阶乘输出即为序列数

枚举操作种数i,+1什么的太麻烦就直接分成$2^{N-i}$段,每段$2^i$个数

然后要交换的话就需要找非严格递增序列($a_{x+1}!=a_x+1$)

超过两个显然不可行,直接return

接下来分类讨论:

如果没有这样的序列,继续dfs

如果有一个,尝试内部一分为二后交换使之满足严格递增

如果有两个,两段分成四段尝试交换

(感谢hzwer的题解 大大减少了我的代码量 两层for分类讨论确实比四个if else美观多辽)

收获:看到二进制不要直接想状压,还有可能是树形结构或者二分搜索

#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=(<<)+;
int n,a[N],tot;
long long ans=,bin[],fac[];
int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void ini()
{
bin[]=fac[]=;
for(int i=;i<=;i++)
bin[i]=bin[i-]<<,fac[i]=1LL*i*fac[i-];
}
bool judge(int p,int k)
{
for(int j=;j<bin[k];j++)
if(a[p+j]!=a[p+j-]+)return ;
return ;
}
void sw_(int x,int y,int k)
{
for(int i=;i<bin[k];i++)
swap(a[x+i],a[y+i]);
}
void dfs(int p,int val)
{
if(p==n+)
{
ans+=fac[val];
return ;
}
int bl1,bl2;bl1=bl2=;
for(int i=;i<=bin[n];i+=bin[p])
if(!judge(i,p))
{
if(!bl1)bl1=i;
else if(!bl2)bl2=i;
else return ;
}
if(!bl1&&!bl2)dfs(p+,val);
else if(bl1&&!bl2)
{
sw_(bl1,bl1+bin[p-],p-);
dfs(p+,val+);
sw_(bl1,bl1+bin[p-],p-);
}
else
{
for(int num1=;num1<;num1++)
for(int num2=;num2<;num2++)
{
sw_(bl1+num1*bin[p-],bl2+num2*bin[p-],p-);
if(judge(bl1,p)&&judge(bl2,p))
{
dfs(p+,val+);
sw_(bl1+num1*bin[p-],bl2+num2*bin[p-],p-);
break;
}
sw_(bl1+num1*bin[p-],bl2+num2*bin[p-],p-);
}
}
}
int main()
{
n=read();
ini();
for(int i=;i<=bin[n];i++)
a[i]=read();
dfs(,);
cout<<ans<<endl;
return ;
}

[SDOI2015]排序 题解 (搜索)的更多相关文章

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

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

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

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

  3. [BZOJ3990]:[SDOI2015]排序(搜索)

    题目传送门 题目描述 小A有一个1-${2}^{N}$的排列A[1..${2}^{N}$],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1≤i≤N), ...

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

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

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

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

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

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

  7. 【LG3322】[SDOI2015]排序

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

  8. MVC5 + EF6 + Bootstrap3 (11) 排序、搜索、分页

    系列教程:MVC5 + EF6 + Bootstrap3 上一节:MVC5 + EF6 + Bootstrap3 (10) 数据查询页面 源码下载:点我下载 我工作的源码:http://www.jin ...

  9. numpy教程:排序、搜索和计数

    http://blog.csdn.net/pipisorry/article/details/51822775 numpy排序.搜索和计数函数和方法.(重新整合过的) ],, , ], [, , ]] ...

随机推荐

  1. C#将数据导入到Excel表格中

    public static DataTable GetExcelToDataTableBySheet(string FileFullPath, string SheetName){           ...

  2. 服务器一般达到多少QPS比较好?

    每秒查询率QPS是对一个特定的查询服务器在规定时间内所处理流量多少的衡量标准,在因特网上,作为域名系统服务器的机器的性能经常用每秒查询率来衡量. 原理:每天80%的访问集中在20%的时间里,这20%时 ...

  3. JavaScript 工作原理之十一-渲染引擎及性能优化小技巧

    原文请查阅这里,略有删减,本文采用知识共享署名 4.0 国际许可协议共享,BY Troland. 本系列持续更新中,Github 地址请查阅这里. 这是 JavaScript 工作原理的第十一章. 迄 ...

  4. python爬虫https://www.imdb.com/chart/top的电影

    目标:爬取https://www.imdb.com/chart/top网页上面的电影top20 直接上main.py代码: #!/usr/bin/python35 # -*- coding:utf-8 ...

  5. HTML5: HTML5 表单元素

    ylbtech-HTML5: HTML5 表单元素 1.返回顶部 1. HTML5 表单元素 HTML5 新的表单元素 HTML5 有以下新的表单元素: <datalist> <ke ...

  6. flex属性flex-grow、flex-shrink、flex-basis

    tip: 1)这些属性写在子元素中,作用于子元素(父元素中应设置display:flex) 2)作用是子元素如何分配父元素的空间 3) flex-grow 是扩展比率,当子元素宽度总和小于父元素宽度时 ...

  7. shell编程:find命令

    写在前面 在linux的日常管理中,find的使用频率很高,熟练掌握对提高工作效率很有帮助. find的语法比较简单,常用参数的就那么几个,比如-name.-type.-ctime等.初学的同学直接看 ...

  8. spark优化——依赖包传入HDFS_spark.yarn.jar和spark.yarn.archive的使用

    一.参数说明 启动Spark任务时,在没有配置spark.yarn.archive或者spark.yarn.jars时, 会看到不停地上传jar,非常耗时:使用spark.yarn.archive可以 ...

  9. 高级UI晋升之自定义view实战(七)

    更多Android高级架构进阶视频学习请点击:https://space.bilibili.com/474380680本篇文章自定义ViewGroup实现瀑布流效果来进行详解dispatchTouch ...

  10. css中的居中问题

    前两天写了一篇关于display:table的用法,里面涉及到居中的问题,这两天愈发觉得css中的居中是一个值得关注的问题,现总结如下. 一.垂直居中 (1)inline或者inline-*元素 1. ...