• [BZOJ3990][SDOI2015]排序(DFS)


    3990: [SDOI2015]排序

    Time Limit: 20 Sec  Memory Limit: 128 MB
    Submit: 902  Solved: 463
    [Submit][Status][Discuss]

    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

    [Submit][Status][Discuss]

    深搜即可,从小到大搜就可以确定这种操作对谁使用了。

    http://hzwer.com/6839.html

     1 #include<cstdio>
     2 #include<algorithm>
     3 #define rep(i,l,r) for (int i=l; i<=r; i++)
     4 typedef long long ll;
     5 using namespace std;
     6 
     7 const int N=5010;
     8 int n,bin[20],a[N];
     9 ll fac[20],ans;
    10 
    11 bool check(int x,int k){ rep(i,x+1,x+k-1) if (a[i]!=a[i-1]+1) return 0; return 1; }
    12 void work(int x,int y,int k){ rep(i,0,k-1) swap(a[x+i],a[y+i]); }
    13 
    14 void dfs(int x,int s){
    15     if (x==n+1) { ans+=fac[s]; return; }
    16     int t1=0,t2=0;
    17     for (int i=1; i<=bin[n]; i+=bin[x])
    18         if (!check(i,bin[x])){
    19             if (!t1) t1=i;
    20             else if (!t2) t2=i;
    21                 else return;
    22         }
    23     if (!t1) { dfs(x+1,s); return; }
    24     if (!t2) work(t1,t1+bin[x-1],bin[x-1]),dfs(x+1,s+1),work(t1,t1+bin[x-1],bin[x-1]);
    25     else
    26         rep(a,0,1) rep(b,0,1){
    27             work(t1+a*bin[x-1],t2+b*bin[x-1],bin[x-1]);
    28             if (check(t1,bin[x]) && check(t2,bin[x])){
    29                 dfs(x+1,s+1);
    30                 work(t1+a*bin[x-1],t2+b*bin[x-1],bin[x-1]);
    31                 break;
    32             }
    33             work(t1+a*bin[x-1],t2+b*bin[x-1],bin[x-1]);
    34     }
    35 }
    36 
    37 int main(){
    38     freopen("bzoj3990.in","r",stdin);
    39     freopen("bzoj3990.out","w",stdout);
    40     scanf("%d",&n); fac[0]=bin[0]=1;
    41     rep(i,1,15) fac[i]=fac[i-1]*i,bin[i]=bin[i-1]<<1;
    42     rep(i,1,bin[n]) scanf("%d",&a[i]);
    43     dfs(1,0); printf("%lld
    ",ans);
    44     return 0;
    45 }
  • 相关阅读:
    good course Very
    HTTP Hypertext Transfer Protocol Overview
    Linux下tar.xz结尾的文件的解压方法
    原来java HttpURLConnection本身就提供了chunk的支持,又是让人一惊啊
    牛人一枚
    V2EX › 花了3个晚上,把readability最新的1.7.1转成了python版的
    13.11. 惯例优先原则(convention over configuration)
    明尼苏达大学
    快速构建实时抓取集群 « 搜索技术博客-淘宝
    Java Practices > Home
  • 原文地址:https://www.cnblogs.com/HocRiser/p/8690648.html
Copyright © 2020-2023  润新知