• BZOJ 3990 [SDOI2015]排序 ——搜索


    【题目分析】

        可以发现,操作的先后顺序是不影响结果的,那么答案就是n!的和。

        可以从小的步骤开始搜索,使得每一个当前最小的块都是上升的数列,然后看看是否可行即可。

        复杂度好像是4^n

    【代码】(哪里写挂了,意会一下就好了)

    #include <cstdio>
    #include <cstring>
    #include <cmath>
    #include <cstdlib>
    
    #include <map>
    #include <set>
    #include <queue>
    #include <string>
    #include <iostream>
    #include <algorithm>
    
    using namespace std;
    
    #define maxn 5005
    #define ll long long
    #define mlog 15
    #define inf 0x3f3f3f3f
    #define F(i,j,k) for (int i=j;i<=k;++i)
    #define D(i,j,k) for (int i=j;i>=k;--i)
    
    void Finout()
    {
        #ifndef ONLINE_JUDGE
        freopen("in.txt","r",stdin);
    //    freopen("out.txt","w",stdout);
        #endif
    }
    
    int Getint()
    {
        int x=0,f=1; char ch=getchar();
        while (ch<'0'||ch>'9') {if (ch=='-') f=-1; ch=getchar();}
        while (ch>='0'&&ch<='9') {x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    
    int a[mlog][maxn],b[maxn],n,cnt=0,s;
    ll ans=0;
    ll fac[mlog]; 
    
    void solve(int now,int n)
    {
    	if (n==1)
    	{
    		ans+=fac[s];
    		return ;
    	}
    	int cnt=0;
    	int pos1=0,pos2=0;
    	for (int i=1;i<=n;i+=2)
    	{
    		if (a[now][i]>a[now][i+1])
    		{
    			cnt++;
    			if (!pos1) pos1=i;
    			else pos2=i;
    		}
    		if (cnt>2) return ;
    	}
    	if (cnt==0)
    	{
    		for (int i=1;i<=n/2;++i)
    			a[now+1][i]=(a[now][i*2-1]+1)/2;
    		solve(now+1,n/2);
    	}
    	else
    	{
    		if (cnt==1)
    		{
    			swap(a[now][pos1],a[now][pos1+1]);
    			s++;
    			for (int i=1;i<=n/2;++i)
    				a[now+1][i]=(a[now][i*2-1]+1)/2;
    			solve(now+1,n/2);
    			s--;
    			swap(a[now][pos1],a[now][pos1+1]);
    		}
    		else
    		{
    			swap(a[now][pos1],a[now][pos2]);
    			if (a[now][pos1]<a[now][pos1+1]&&a[now][pos2]<a[now][pos2+1])
    			{
    				s++;
    				for (int i=1;i<=n/2;++i)
    					a[now+1][i]=(a[now][i*2-1]+1)/2;
    				solve(now+1,n/2);
    				s--;
    			}
    			swap(a[now][pos1],a[now][pos2]);
    			
    			
    			
    			swap(a[now][pos1+1],a[now][pos2]);
    			if (a[now][pos1]<a[now][pos1+1]&&a[now][pos2]<a[now][pos2+1])
    			{
    				s++;
    				for (int i=1;i<=n/2;++i)
    					a[now+1][i]=(a[now][i*2-1]+1)/2;
    				solve(now+1,n/2);
    				s--;
    			}
    			swap(a[now][pos1+1],a[now][pos2]);
    			
    			
    			swap(a[now][pos1],a[now][pos2+1]);
    			if (a[now][pos1]<a[now][pos1+1]&&a[now][pos2]<a[now][pos2+1])
    			{
    				s++;
    				for (int i=1;i<=n/2;++i)
    					a[now+1][i]=(a[now][i*2-1]+1)/2;
    				solve(now+1,n/2);
    				s--;
    			}
    			swap(a[now][pos1],a[now][pos2+1]);
    			
    			
    			swap(a[now][pos1+1],a[now][pos2+1]);
    			if (a[now][pos1]<a[now][pos1+1]&&a[now][pos2]<a[now][pos2+1])
    			{
    				s++;
    				for (int i=1;i<=n/2;++i)
    					a[now+1][i]=(a[now][i*2-1]+1)/2;
    				solve(now+1,n/2);
    				s--;
    			}
    			swap(a[now][pos1+1],a[now][pos2+1]);
    		}
    	}
    	return ;
    }
    
    int main()
    {
        Finout();
        n=Getint();
        n=1<<n;
        fac[0]=1;
        F(i,1,12) fac[i]=fac[i-1]*i;
        F(i,1,n) a[1][i]=Getint();
        solve(1,n);
        cout<<ans<<endl;
    }
    

      

  • 相关阅读:
    android音乐播放器开发 SweetMusicPlayer 摇一摇换歌
    kernel logo到开机动画之间闪现黑屏(android 5.X)
    [DLX反复覆盖] hdu 3656 Fire station
    使用清华源 tensorflow 安装
    类别不平衡问题之SMOTE算法(Python imblearn极简实现)
    在Ubuntu 18.04上安装OpenCV 4(C ++和Python)
    OpenCV
    git clone速度太慢的解决办法
    OpenCV 3.4.2 环境搭建(适用于Ubuntu 一键安装)
    ubuntu16.04安装opencv3.4.1教程
  • 原文地址:https://www.cnblogs.com/SfailSth/p/6271177.html
Copyright © 2020-2023  润新知