zoukankan      html  css  js  c++  java
  • Bzoj3990 [SDOI2015]排序

    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=5600;
    10 int read(){
    11     int x=0,f=1;char ch=getchar();
    12     while(ch<'0' || ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    13     while(ch>='0' && ch<='9'){x=x*10+ch-'0';ch=getchar();}
    14     return x*f;
    15 }
    16 int a[mxn];
    17 //int cp[mxn];
    18 int n,ed;
    19 LL pw[30];
    20 LL jc[30];
    21 void init(){
    22     pw[0]=1;jc[1]=1;
    23     for(int i=1;i<=n;i++)pw[i]=pw[i-1]*2;
    24     for(int i=2;i<=n;i++)jc[i]=jc[i-1]*i;
    25     return;
    26 }
    27 void Swap(int st1,int st2,int x){
    28     for(int i=0;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=1;i<pw[k];i++)
    34         if(a[x+i]!=a[x+i-1]+1)return 0;
    35     return 1;
    36 }
    37 bool pd2(){
    38     for(int i=1;i<=n;i++){
    39         if(a[i]!=a[i-1]+1)return 0;
    40     }
    41     return 1;
    42 }
    43 LL ans=0;
    44 void DFS(int now,int res){//2^now 总使用操作数 
    45     if(now>n){
    46         ans+=jc[res];
    47         return;
    48     }
    49     int cnt=0,pos[4];
    50     int i,j;
    51     for(i=1;i<=ed;i+=pw[now]){
    52         if(!pd(i,now)){
    53             pos[++cnt]=i;
    54             if(cnt>2)return;
    55         }
    56     }
    57     if(!cnt){DFS(now+1,res);return;}
    58     if(cnt==1){
    59         Swap(pos[1],pos[1]+pw[now-1],now-1);
    60         DFS(now+1,res+1);
    61         Swap(pos[1],pos[1]+pw[now-1],now-1);
    62     }
    63     else{
    64         for(i=0;i<=1;i++){
    65             bool flag=0;
    66             for(j=0;j<=1 && !flag;j++){
    67                 Swap(pos[1]+i*pw[now-1],pos[2]+j*pw[now-1],now-1);
    68                 if(pd(pos[1],now) && pd(pos[2],now)){
    69                     DFS(now+1,res+1);
    70                     flag=1;
    71                 }
    72                 Swap(pos[1]+i*pw[now-1],pos[2]+j*pw[now-1],now-1);
    73             }
    74         }
    75     }
    76     
    77 }
    78 int main(){
    79     n=read();
    80     init();
    81     int i,j;
    82     ed=pw[n];
    83     for(i=1;i<=ed;i++){
    84         a[i]=read();
    85     }
    86     DFS(1,0);
    87     printf("%lld
    ",ans);
    88     return 0;
    89 }
  • 相关阅读:
    MyBatis XML 配置文件 properties 元素扩展
    ranche2.0-CN
    xpath_note
    使用face_recognition进行人脸特征检测
    spring+mybatis+mysql5.7实现读写分离,主从复制
    js 创建对象的多种方式
    吴裕雄 python 机器学习——人工神经网络与原始感知机模型
    吴裕雄 python 机器学习——人工神经网络感知机学习算法
    吴裕雄 python 机器学习——支持向量机非线性回归SVR模型
    吴裕雄 python 机器学习——支持向量机线性回归SVR模型
  • 原文地址:https://www.cnblogs.com/SilverNebula/p/6266993.html
Copyright © 2011-2022 走看看