3990: [SDOI2015]排序

题意:\(2^n\)的一个排列,给你n种操作,第i种把每\(2^{i-1}\)个数看成一段,交换任意两段。问是这个序列有序的操作方案数,两个操作序列不同,当且仅当操作个数不同,或者至少一个操作不同(种类不同或者操作位置不同).


R1D1T1

先玩一下样例

发现操作的顺序其实没有影响

从小到大考虑,设当前处理的有n段,可以分成\(\frac{n}{2}\)个二元组\((a_i, a_{i+1})\),每个都要满足\(a_i +1 = a_{i+1}\),找出有几个不满足,如果\(\le 2\)个那么枚举如何交换然后再处理\(\frac{n}{2}\)段的时候

注意每种成立的交换就要继续搜索...一开始没这么做然后35分...

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=(1<<12) + 5, INF=1e9+5;
inline int read(){
char c=getchar();int x=0,f=1;
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();}
return x*f;
} int bin, n, t[15][N], fac[N]; ll ans=0;
inline bool check(int *a, int x, int y) {return a[x]+1 == a[x+1] && a[y]+1 == a[y+1];}
inline void ready(int *a, int n) {
for(int i=1; i<=n; i++) a[i] = a[i*2-1]/2 + 1;
}
void dfs(int d, int n, int now) { //printf("dfs %d %d %d\n",d,n,now);
if(d>=bin) {ans += fac[now]; return;}
int *a = t[d], *b = t[d+1];
//for(int i=1; i<=n; i++) printf("%d ",a[i]); puts(" a"); int tot=0, li[5];
for(int i=1; i<=n; i+=2)
if(a[i]+1 != a[i+1]) {li[++tot]=i; if(tot>2) return;} int x=li[1], y=li[2];
if(tot==2) {
swap(a[x], a[y]);
if(check(a, x, y)) memcpy(b, a, sizeof(int)*(n+1)), ready(b, n>>1), dfs(d+1, n>>1, now+1);
swap(a[x], a[y]); swap(a[x], a[y+1]);
if(check(a, x, y)) memcpy(b, a, sizeof(int)*(n+1)), ready(b, n>>1), dfs(d+1, n>>1, now+1);
swap(a[x], a[y+1]); swap(a[x+1], a[y]);
if(check(a, x, y)) memcpy(b, a, sizeof(int)*(n+1)), ready(b, n>>1), dfs(d+1, n>>1, now+1);
swap(a[x+1], a[y]); swap(a[x+1], a[y+1]);
if(check(a, x, y)) memcpy(b, a, sizeof(int)*(n+1)), ready(b, n>>1), dfs(d+1, n>>1, now+1);
swap(a[x+1], a[y+1]);
} else if(tot==0) memcpy(b, a, sizeof(int)*(n+1)), ready(b, n>>1), dfs(d+1, n>>1, now);
else if(tot==1) swap(a[x], a[x+1]), memcpy(b, a, sizeof(int)*(n+1)), ready(b, n>>1), dfs(d+1, n>>1, now+1);
}
int main() {
freopen("in","r",stdin);
bin=read(); n=1<<bin;
fac[0]=1;
for(int i=1; i<=bin; i++) fac[i]=fac[i-1]*i;
for(int i=1; i<=n; i++) t[0][i]=read();
dfs(0, n, 0);
printf("%lld", ans);
}

BZOJ 3990: [SDOI2015]排序 [搜索]的更多相关文章

  1. BZOJ 3990 [SDOI2015]排序 ——搜索

    [题目分析] 可以发现,操作的先后顺序是不影响结果的,那么答案就是n!的和. 可以从小的步骤开始搜索,使得每一个当前最小的块都是上升的数列,然后看看是否可行即可. 复杂度好像是4^n [代码](哪里写 ...

  2. BZOJ.3990.[SDOI2015]排序(DFS)

    题目链接 操作序列的顺序显然是无关的,所以只需按特定顺序求出一个长度为\(l\)的操作序列,它对答案的贡献为\(l!\). 我们从小到大枚举所有选择.若当前为第\(i\)个,如果有一段长度为\(2^i ...

  3. BZOJ 3990 [SDOI2015]排序

    题解: 首先很容易看出各个操作是互不影响的,即对于一个合法的操作序列,我们可以任意交换两个操作的位置而不影响合法性. 因此我们可以忽略操作先后的影响,只考虑这个操作是否会出现在操作序列中. 如果用2n ...

  4. [bzoj3990][SDOI2015]排序-搜索

    Brief Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1<=i<= ...

  5. 【搜索】BZOJ 3990: 【Sdoi 2015】排序

    3990: [SDOI2015]排序 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 336  Solved: 164[Submit][Status][ ...

  6. [BZOJ3990][SDOI2015]排序(DFS)

    3990: [SDOI2015]排序 Time Limit: 20 Sec  Memory Limit: 128 MBSubmit: 902  Solved: 463[Submit][Status][ ...

  7. BZOJ 3990: [SDOI2015]排序(搜索+剪枝)

    [SDOI2015]排序 Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1< ...

  8. 006-筛选分类排序搜索查找Filter-Classificatio-Sort-Search-Find-Seek-Locate

    006-筛选分类排序搜索查找Filter-Classificatio-Sort-Search-Find-Seek-Locate https://www.cnblogs.com/delphixx/p/1 ...

  9. bzoj 3991: [SDOI2015]寻宝游戏 虚树 set

    目录 题目链接 题解 代码 题目链接 bzoj 3991: [SDOI2015]寻宝游戏 题解 发现每次答案就是把虚树上的路径*2 接在同一关键点上的点的dfs序是相邻的 那么用set动态维护dfs序 ...

随机推荐

  1. 2017ecjtu-summer training #3 POJ3264

                                                                                                        ...

  2. LightOJ DNA Prefix(字典树+dfs)

    http://acm.hust.edu.cn/vjudge/contest/view.action?cid=121897#problem/F F - DNA Prefix Time Limit:200 ...

  3. hdu_1711Number Sequence(kmp)

    Number Sequence Time Limit: 10000/5000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) ...

  4. jq实现上传头像并实时预览功能

    效果 页面结构 <form action="" name="form0" id="form0"> <input type= ...

  5. mysql 手册关于修改列字符编码的一个bug

    项目因为历史原因使用了 GBK编码,遇到非GBK编码字符时出现乱码问题,情况比较严重,暂时先打算修改 列的字符编码为 utf8mb4. 查看 mysql 手册: 用 GBK 编码转 utf8 进行说明 ...

  6. Kafka集群的搭建

    Kafka集群的搭建 node1   node2   node3 kafka须用版本(kafka-0.8.2.2),否则不兼容spark1.6 1.启动zookeeper集群node1   node2 ...

  7. javascript如何自动去除所有空格?

    1.jquery自带了trim方法:    $.trim(" abc ") // abc 2.自己写方法: function trim(str) { return str.repl ...

  8. JavaScript总结学习一:js中构造函数与普通函数的区别

    构造函数不仅只出现在JavaScript中,它同样存在于很多主流的程序语言里,比如c++.Java.PHP等等.与这些主流程序语言一样,构造函数在js中的作业一样,也是用来创建对象时初始化对象,并且总 ...

  9. sql 时间转换问题 from_unixtime() UNIX_TIMESTAMP()

    http://blog.csdn.net/test_soy/article/details/50328367 from_unixtime()是MySQL里的时间函数 date为需要处理的参数(该参数是 ...

  10. 记一些安卓app反编译修改的记录

    2017-12-2209:00:40 好几天没有写过博客了,因为马上要期末考试,只能暂且放下我的小玩物,专心复习我的期末考试. 今天突然想设置一个安卓的栏目,记录下自己从高中就爱玩的一些东西,像刷机呀 ...