$ SDOI2015 $ sort

\ (SDOI2015 \) Sort

Search good title.

This question has a lot ofEvidentConclusions. . . Really, I did not find or no sense to a lot of trouble. . .

First, the operation sequence may be out of sequence, that is, for a set of operations (the number of elements of \ (N \) ) corresponding to the sequence number of the operation is set up \ (N! \)

Then we consider small to large segments exchange, in the middle of this process, as long as we ensure that each section is continuously increasing on it to ensure that the end result is continuously increasing.

You may wish to set the current sub-segment for the \ (K \) .

We need to verify it in the segment length \ (K-1 \) exchanged when meets each segment is continuously increasing.

Then consider the current \ (K \) in the segment, with a couple of no increase.

Not plucked out of all increments and then twenty-two exchange?

It can be measured, but we have to prune, because this is a search

Here is a pruning: if more than \ (4 \) segments out of sequence can be pulled out, do not come out of the exchange.

All in all, this is a question of analysis plus pruning cancer search topic.

#include<bits/stdc++.h>
using namespace std;
#define int long long
inline int read()
{
    int f=1,w=0;char x=0;
    while(x<'0'||x>'9') {if(x=='-') f=-1; x=getchar();}
    while(x!=EOF&&x>='0'&&x<='9') {w=(w<<3)+(w<<1)+(x^48);x=getchar();}
    return w*f;
}
const int N=1LL<<15;
int n,Fac[20],A[N],Ans;
inline bool Check(int K)
{
    for(int i=1;i<=1<<(n-K);i++)
        if(A[(i-1)*(1<<K)+1]+(1<<(K-1))!=A[(i-1)*(1<<K)+1+(1<<(K-1))])
            return 0;
    return 1;
}
inline void SWAP(int i,int j,int K)
{
    for(int k=1;k<=1<<K;k++) swap(A[i+k-1],A[j+k-1]);
}
inline void Dfs(int K,int Cnt)
{
    int Tmp[5],Sum=0;
    if(K&&!Check(K)) return ;
    if(K==n) {Ans+=Fac[Cnt];return ;}
    Dfs(K+1,Cnt);
    for(int i=1;i<=1<<(n-K);i+=2)
        if(A[(i-1)*(1<<K)+1]+(1<<K)!=A[(i)*(1<<K)+1])
            {if(Sum==4) return ;Tmp[++Sum]=i,Tmp[++Sum]=i+1;}
    if(!Sum||Sum>4) return ;
    for(int i=1;i<=Sum;i++)
        for(int j=i+1;j<=Sum;j++)
        {
            SWAP((Tmp[i]-1)*(1<<K)+1,(Tmp[j]-1)*(1<<K)+1,K);
            Dfs(K+1,Cnt+1);
            SWAP((Tmp[i]-1)*(1<<K)+1,(Tmp[j]-1)*(1<<K)+1,K);
        }
}
signed main(){
#ifndef ONLINE_JUDGE
    freopen("A.in","r",stdin);
#endif
    n=read(),Fac[0]=1;
    for(int i=1;i<=12;i++) Fac[i]=Fac[i-1]*i;
    for(int i=1;i<=(1<<n);i++) A[i]=read();
    Dfs(0,0);printf("%lld",Ans);
}

Guess you like

Origin www.cnblogs.com/wo-shi-zhen-de-cai/p/11803905.html