Time Limit: 20 Sec  Memory Limit: 128 MB
Submit: 651  Solved: 338

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

HINT

100%的数据, 1<=N<=12.

Source

DFS

思考一波可以发现,每种操作之间是互不影响的。

再思考一波发现,一种操作只能交换对应长度的两个区间,如果不单调的区间超过两个,就不可行了。

然后注意到数据范围,大概可以强行DFS

%一下神犇popoQQQ http://blog.csdn.net/popoqqq/article/details/45073989

  1. /*by SilverN*/
  2. #include<iostream>
  3. #include<algorithm>
  4. #include<cstring>
  5. #include<cstdio>
  6. #include<cmath>
  7. #define LL long long
  8. using namespace std;
  9. const int mxn=;
  10. int read(){
  11. int x=,f=;char ch=getchar();
  12. while(ch<'' || ch>''){if(ch=='-')f=-;ch=getchar();}
  13. while(ch>='' && ch<=''){x=x*+ch-'';ch=getchar();}
  14. return x*f;
  15. }
  16. int a[mxn];
  17. //int cp[mxn];
  18. int n,ed;
  19. LL pw[];
  20. LL jc[];
  21. void init(){
  22. pw[]=;jc[]=;
  23. for(int i=;i<=n;i++)pw[i]=pw[i-]*;
  24. for(int i=;i<=n;i++)jc[i]=jc[i-]*i;
  25. return;
  26. }
  27. void Swap(int st1,int st2,int x){
  28. for(int i=;i<pw[x];i++)
  29. swap(a[st1+i],a[st2+i]);
  30. return;
  31. }
  32. bool pd(int x,int k){
  33. for(int i=;i<pw[k];i++)
  34. if(a[x+i]!=a[x+i-]+)return ;
  35. return ;
  36. }
  37. bool pd2(){
  38. for(int i=;i<=n;i++){
  39. if(a[i]!=a[i-]+)return ;
  40. }
  41. return ;
  42. }
  43. LL ans=;
  44. void DFS(int now,int res){//2^now 总使用操作数
  45. if(now>n){
  46. ans+=jc[res];
  47. return;
  48. }
  49. int cnt=,pos[];
  50. int i,j;
  51. for(i=;i<=ed;i+=pw[now]){
  52. if(!pd(i,now)){
  53. pos[++cnt]=i;
  54. if(cnt>)return;
  55. }
  56. }
  57. if(!cnt){DFS(now+,res);return;}
  58. if(cnt==){
  59. Swap(pos[],pos[]+pw[now-],now-);
  60. DFS(now+,res+);
  61. Swap(pos[],pos[]+pw[now-],now-);
  62. }
  63. else{
  64. for(i=;i<=;i++){
  65. bool flag=;
  66. for(j=;j<= && !flag;j++){
  67. Swap(pos[]+i*pw[now-],pos[]+j*pw[now-],now-);
  68. if(pd(pos[],now) && pd(pos[],now)){
  69. DFS(now+,res+);
  70. flag=;
  71. }
  72. Swap(pos[]+i*pw[now-],pos[]+j*pw[now-],now-);
  73. }
  74. }
  75. }
  76.  
  77. }
  78. int main(){
  79. n=read();
  80. init();
  81. int i,j;
  82. ed=pw[n];
  83. for(i=;i<=ed;i++){
  84. a[i]=read();
  85. }
  86. DFS(,);
  87. printf("%lld\n",ans);
  88. return ;
  89. }

Bzoj3990 [SDOI2015]排序的更多相关文章

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

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

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

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

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

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

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

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

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

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

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

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

  7. 【LG3322】[SDOI2015]排序

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

  8. SDOI2015 排序

    SDOI2015 排序 今天看到这道题,没有一点思路,暴力都没的打...还是理解错题意了,操作不同位置不是说改不同的区间,而是不同操作的顺序...考场上如果知道这个的话最少暴力拿一半啊,因为正解本来就 ...

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

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

随机推荐

  1. Reverse Interger

    Reverse digits of an integer. Example1: x = 123, return 321Example2: x = -123, return -321 Have you ...

  2. SQL Server 2008连接字符串写法大全(摘自网络)

    一..NET Framework Data Provider for SQL Server 类型:.NET Framework类库使用:System.Data.SqlClient.SqlConnect ...

  3. javascript禁止输入数字

    function onkeypressIsNumber(){ var mainForm = document.mainForm;//mainForm是form表单的ID for(var i=0; i& ...

  4. grails&groovy的IllegalArgument异常

    我在开发的过程中遇到了这样一个异常,总是提示IllegalArgument异常,代码大致如下: if(haomgl.save(flush:true)){ //更新库存:状态为2的位置存煤 def cu ...

  5. 删除左右两边的空格trim

    js中却没有trim()/ltrim()和rtrim()内置方法,所以需要自己写 写成类的方法格式如下:(str.trim();) <script language="javascri ...

  6. 解决octave for windows安装包无法通过SourceForge下载的问题

    近期SourceForge访问不了,可以通过访问SourceForge的ftp镜像ftp://sourceforge.nchc.org.tw/进行下载: ftp下载工具可以使用FileZilla,可在 ...

  7. Documentation/sched-bwc.txt 的中文翻译

    Chinese translated version of Documentation/sched-bwc.txt If you have any comment or update to the c ...

  8. Extjs4 自定义组件

    Ext.onReady (function () { Ext.define ('MydesktopIcon', { /* Begin Definitions */ alias: 'widget.des ...

  9. 可以把一些常用的方法,写入js文件,引入html界面

    这样,可以在多处应用.更好一些.缺点是不够灵活. 优点是,一处修改,多处应用. 函数这东西,一般都是先加载的,之后就可以随便调用了. function delquestion(obj){ //conf ...

  10. "红色病毒"问题 HDU 2065 递推+找循环节

    题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=2065 递推类题目, 可以考虑用数学方法来做, 但是明显也可以有递推思维来理解. 递推的话基本就是状态 ...