[SDOI2015]排序 题解 (搜索)
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认为两个操作序列不同,当且仅当操作个数不同,或者至少一个操作不同(种类不同或者操作位置不同).
Input
第一行,一个整数N
Output
一个整数表示答案
Sample Input
7 8 5 6 1 2 4 3
Sample Output
6
正解居然是搜索,考场上看这板儿B是个神仙状压就skip掉了
后悔啊……把猛肝某APIO2016T1的时间放这题上怎么还没30分啊……
手%几组数据可以发现,操作序列的合法性与顺序无瓜
所以只需确定序列中有没有第i种操作,最后将统计结果的阶乘输出即为序列数
枚举操作种数i,+1什么的太麻烦就直接分成$2^{N-i}$段,每段$2^i$个数
然后要交换的话就需要找非严格递增序列($a_{x+1}!=a_x+1$)
超过两个显然不可行,直接return
接下来分类讨论:
如果没有这样的序列,继续dfs
如果有一个,尝试内部一分为二后交换使之满足严格递增
如果有两个,两段分成四段尝试交换
(感谢hzwer的题解 大大减少了我的代码量 两层for分类讨论确实比四个if else美观多辽)
收获:看到二进制不要直接想状压,还有可能是树形结构或者二分搜索
#include<cstdio>
#include<iostream>
#include<cstring>
using namespace std;
const int N=(<<)+;
int n,a[N],tot;
long long ans=,bin[],fac[];
int read()
{
int x=,f=;char ch=getchar();
while(ch<''||ch>''){if(ch=='-')f=-;ch=getchar();}
while(ch>=''&&ch<=''){x=x*+ch-'';ch=getchar();}
return x*f;
}
void ini()
{
bin[]=fac[]=;
for(int i=;i<=;i++)
bin[i]=bin[i-]<<,fac[i]=1LL*i*fac[i-];
}
bool judge(int p,int k)
{
for(int j=;j<bin[k];j++)
if(a[p+j]!=a[p+j-]+)return ;
return ;
}
void sw_(int x,int y,int k)
{
for(int i=;i<bin[k];i++)
swap(a[x+i],a[y+i]);
}
void dfs(int p,int val)
{
if(p==n+)
{
ans+=fac[val];
return ;
}
int bl1,bl2;bl1=bl2=;
for(int i=;i<=bin[n];i+=bin[p])
if(!judge(i,p))
{
if(!bl1)bl1=i;
else if(!bl2)bl2=i;
else return ;
}
if(!bl1&&!bl2)dfs(p+,val);
else if(bl1&&!bl2)
{
sw_(bl1,bl1+bin[p-],p-);
dfs(p+,val+);
sw_(bl1,bl1+bin[p-],p-);
}
else
{
for(int num1=;num1<;num1++)
for(int num2=;num2<;num2++)
{
sw_(bl1+num1*bin[p-],bl2+num2*bin[p-],p-);
if(judge(bl1,p)&&judge(bl2,p))
{
dfs(p+,val+);
sw_(bl1+num1*bin[p-],bl2+num2*bin[p-],p-);
break;
}
sw_(bl1+num1*bin[p-],bl2+num2*bin[p-],p-);
}
}
}
int main()
{
n=read();
ini();
for(int i=;i<=bin[n];i++)
a[i]=read();
dfs(,);
cout<<ans<<endl;
return ;
}
[SDOI2015]排序 题解 (搜索)的更多相关文章
- BZOJ 3990: [SDOI2015]排序(搜索+剪枝)
[SDOI2015]排序 Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1< ...
- [sdoi2015]排序(搜索+剪枝优化)
Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1<=i<=N),第i中 ...
- [BZOJ3990]:[SDOI2015]排序(搜索)
题目传送门 题目描述 小A有一个1-${2}^{N}$的排列A[1..${2}^{N}$],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1≤i≤N), ...
- BZOJ3990 [SDOI2015]排序 【搜索】
题目 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1<=i<=N),第i中操作为将序列从左到 ...
- BZOJ3990:[SDOI2015]排序——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=3990 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作 ...
- BZOJ 3990: [SDOI2015]排序 [搜索]
3990: [SDOI2015]排序 题意:\(2^n\)的一个排列,给你n种操作,第i种把每\(2^{i-1}\)个数看成一段,交换任意两段.问是这个序列有序的操作方案数,两个操作序列不同,当且仅当 ...
- 【LG3322】[SDOI2015]排序
[LG3322][SDOI2015]排序 题面 洛谷 题解 交换顺序显然不影响答案,所以每种本质不同的方案就给答案贡献次数的阶乘. 从小往大的交换每次至多\(4\)中决策,复杂度\(O(4^n)\). ...
- MVC5 + EF6 + Bootstrap3 (11) 排序、搜索、分页
系列教程:MVC5 + EF6 + Bootstrap3 上一节:MVC5 + EF6 + Bootstrap3 (10) 数据查询页面 源码下载:点我下载 我工作的源码:http://www.jin ...
- numpy教程:排序、搜索和计数
http://blog.csdn.net/pipisorry/article/details/51822775 numpy排序.搜索和计数函数和方法.(重新整合过的) ],, , ], [, , ]] ...
随机推荐
- 07-图5 Saving James Bond - Hard Version(30 分)
This time let us consider the situation in the movie "Live and Let Die" in which James Bon ...
- ZROI week5
考试 Part 简单题,从结尾倒着扫一遍就行. Pref 选一个最长的好的序列. 题目有点小简单,似乎直接哈希就行,然后还打了一遍\(kmp\). Chess 一道很不错的题目,用异或维护修改即可. ...
- (转)Spring Boot干货系列:(三)启动原理解析
转:http://tengj.top/2017/03/09/springboot3/ 前言 前面几章我们见识了SpringBoot为我们做的自动配置,确实方便快捷,但是对于新手来说,如果不大懂Spri ...
- ArcGIS Runtime SDK for .NET (Quartz Beta)之连接ArcGIS Portal
1. 介绍 ArcGIS Portal作为ArcGIS平台的中枢,在ArcGIS体系中起着至关重要的地位.在ArcGIS Runtime的新架构Quartz中添加了连接ArcGIS Portal(或A ...
- C++笔试题之宏定义相关
1. #define CALC(X) X*X int i; i=CALC(+)/(+); cout<<i<<endl; 输出:31 宏定义在替换处展开为:i = 5+5*5+5 ...
- javaScript 通过location对象获取项目的url
项目中有些要通过jQuery 动态加载,其中需要一些路径,使用相对路径会出现错误,报 $("#t1").html("设置或返回从井号 (#) 开始的 URL(锚)---& ...
- Rust <0>:源代码组织,Cargo 入门
Rust 源代码组织,使用配套的 Cargo 工具,其功能强大,程序员可摆脱 C/C++ 中需要自行维护 make.cmake 之类配置的工作量. 初始化一个项目: cargo new --bin h ...
- python基础【第五篇】
python第三节 1.整型及布尔值 1.1 进制转换 十进制 ----二进制 二进制 ----十进制 8421方法与普通计算 python中十进制转二进制示例:bin(51)>>> ...
- python 包管理工具 pip 的配置
近几年来,python的包管理系统pip 越来越完善, 尤其是对于 windows场景下,pip大大改善了python的易用性. https://www.cnblogs.com/yvivid/p/pi ...
- js保留两位小数的方法
js保留两位小数的方法如下 1.toFixed()方法 需注意,保留两位小数,将数值类型的数据改变成了字符串类型 2.Math.floor(),不四舍五入 ,向下取整 注意,不改变数据类型 3.字符串 ...