[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排序.搜索和计数函数和方法.(重新整合过的) ],, , ], [, , ]] ...
随机推荐
- imp需要
导入全部: imp user/password@10.10.10.10:1521/orcl file = C:\Users\Administrator\Desktop\20170404230000.d ...
- CentOS 安装MySQL5.7 源码方式安装
MySQL rpm方式安装:https://www.cnblogs.com/deverz/p/9560403.html 1.卸载已经安装的MySQL yum list installed mysqlr ...
- 基于C#的波形显示控件的实现[转]
编者记: 09年暑假正好在学院实验室呆了一段时间,做了个完整的上位机软件(具体实现:根据下位机的指令,实现通过串口来操纵下位机进行实验,并将采集的数据进行处理和保存,并以图形的方式显示),整个项目边学 ...
- JQ-jQuery-Ajax:jQuery Ajax 操作函数
ylbtech-JQ-jQuery-Ajax:jQuery Ajax 操作函数 1.返回顶部 1. jQuery Ajax 操作函数 jQuery 库拥有完整的 Ajax 兼容套件.其中的函数和方法允 ...
- Python单元测试示例
这是使用单元测试框架unittest进行的单元测试,并输出测试结果. 首先定义一个类,三个方法.第一个方法是判断两个字符串是否相等,第二个方法是判断结果为真:第三个方法也是判断两个字符串相等. 然后是 ...
- Sublime text 3 3103 注册码(2016.2.9更新)
Sublime text 3 (Build 3103) license key,these all tested available on 2016/02/10 .Feel free to enjoy ...
- python正常时间和unix时间戳相互转换的方法
python正常时间和unix时间戳相互转换的方法 本文实例讲述了python正常时间和unix时间戳相互转换的方法.分享给大家供大家参考.具体分析如下: 这段代码可以用来转换常规时间格式为unix时 ...
- 力扣算法——141LinkedListCycel【E】
Given a linked list, determine if it has a cycle in it. To represent a cycle in the given linked lis ...
- GCD 与XOR
题目:UVA12716 题意: 问 gcd(i,j) = i ^ j 的对数(j <=i <= N ) N的范围为30000000,有10000组样例 分析: 有几个结论:(1)若 a ...
- 安装APK到android设备那些事儿
APK是AndroidPackage的缩写,即Android系统的应用软件安装包(apk).APK是类似Symbian Sis或Sisx的文件格式.通过将APK文件直接传到Android模拟器或And ...