bzoj3990: [SDOI2015]排序
来源:互联网 发布:飞歌导航 高德 端口 编辑:程序博客网 时间:2024/05/22 04:46
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.
题意
自己看
题解
很容易知道,顺序是没有关系的,最后组合一下就好了
然后呢,我们知道,一般移动方案是很少的,因为你每一堆只能移动一次
其实就是恶心的暴力搜索题。。
CODE
#include<cstdio>#include<cstdlib>#include<algorithm>#include<iostream>#include<cstring>using namespace std;const int N=1<<13;int n;int s[N];inline int read(){ 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 ans=0;int tt[15];void SWAP(int a,int b,int x){ for (int u=0;u<x;u++) swap(s[a+u],s[b+u]);}void dfs (int x,int y)//我们管理的范围{/* printf("%d\n",x); for (int u=1;u<=n;u++) printf("%d ",s[u]); system("pause");*/ int L[N],R[N];//最左位和最右位 if (x==n) { ans+=tt[y]; return ; } int cnt=0; for (int u=1;u<=n;u+=x) R[cnt]=u-1,L[++cnt]=u; R[cnt]=n; int tf=0; int X=-1,Y=-1; for (int u=1;u<=cnt;u+=2) if (s[R[u]]+1!=s[L[u+1]]) { if (tf==0) X=u; else if (tf==1) Y=u; else return ; tf++; } if (tf==0) dfs(x*2,y); //现在知道X和Y有问题 if (Y==-1) { if (s[R[X+1]]+1==s[L[X]]) { SWAP(L[X+1],L[X],x); dfs(x*2,y+1); SWAP(L[X+1],L[X],x); } return ; } if (s[R[X]]+1==s[L[Y+1]]&&s[R[Y]]+1==s[L[X+1]])//这个是X和Y交换 { SWAP(L[X],L[Y],x); dfs(x*2,y+1); SWAP(L[X],L[Y],x); } if (s[R[Y]]+1==s[L[X]]&&s[R[Y+1]]+1==s[L[X+1]])//这个是X和Y+1交换 { SWAP(L[X],L[Y+1],x); dfs(x*2,y+1); SWAP(L[X],L[Y+1],x); } if (s[R[X]]+1==s[L[Y]]&&s[R[X+1]]+1==s[L[Y+1]])//这个是X+1和Y交换 { SWAP(L[X+1],L[Y],x); dfs(x*2,y+1); SWAP(L[X+1],L[Y],x); } if (s[R[X]]+1==s[L[Y+1]]&&s[R[Y]]+1==s[L[X+1]])//这个是X+1和Y+1交换 { SWAP(L[X+1],L[Y+1],x); dfs(x*2,y+1); SWAP(L[X+1],L[Y+1],x); }}int main(){ scanf("%d",&n);n=1<<n; for (int u=1;u<=n;u++) scanf("%d",&s[u]); tt[0]=1; for (int u=1;u<=14;u++) tt[u]=tt[u-1]*u; dfs(1,0);//深度 printf("%d\n",ans); return 0;}
阅读全文
0 0
- 【SDOI2015】【BZOJ3990】排序
- 【bzoj3990】[SDOI2015]排序 DFS
- 【bzoj3990】【SDOI2015】【排序】【dfs】
- bzoj3990【SDOI2015】排序
- 【SDOI2015】bzoj3990 排序
- bzoj3990 [SDOI2015]排序 dfs
- bzoj3990: [SDOI2015]排序
- 【BZOJ3990】【SDOI2015】排序
- [bzoj3990][SDOI2015]排序 搜索
- 【BZOJ3990】【SDOI2015】排序
- 【bzoj3990】 SDOI2015排序 dfs搜索+剪枝
- 【BZOJ3990】排序(SDOI2015)-DFS+贪心
- 【BZOJ 3990】 [SDOI2015]排序
- BZOJ 3990: [SDOI2015]排序
- 【BZOJ 3990】 [SDOI2015]排序
- 3990: [SDOI2015]排序
- BZOJ 3990 [SDOI2015] 排序
- BZOJ 3990 Sdoi2015 排序 DFS
- matlab牛顿插值法
- 贴一下自己写的关于excel导出商品的类
- 状压dp——洛谷P3112 [USACO14DEC]后卫马克Guard Mark
- 第二周项目--程序的多文件组织
- 数字图像分类
- bzoj3990: [SDOI2015]排序
- 常用的类包
- 欢迎使用CSDN-markdown编辑器
- node服务器如何生成有logo和背景的带参数二维码
- bean 的生命周期和后处理器
- 多态
- Anomaly Detection-异常检测算法(Coursera-Ng-ML课程)
- pg基于时间点的恢复(PITR)
- 一步一步学Spring Boot(三)视频发布了~~~