[bzoj3990][SDOI2015]排序-搜索
Brief Description
小A有一个1-2N的排列A[1..2N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1<=i<=N),第i中操作为将序列从左到右划分为2{N-i+1}段,每段恰好包括2{i-1}个数,然后整体交换其中两段.小A想知道可以将数组A从小到大排序的不同的操作序列有多少个,小A认为两个操作序列不同,当且仅当操作个数不同,或者至少一个操作不同(种类不同或者操作位置不同).
Algorithm Design
首先不难发现操作顺序不影响答案, 我们只需要考察每种操作是否选中, 若选中交换哪两块就好了. 一个合法的操作序列如果有\(n\)个操作, 那么可以给答案\(contribute\ n!\). 我们从小到大考察每一种操作, 首先, 可以知道, 对于操作\(2^i\), 序列肯定已经被分成了\(2^{n-i+1}\)个有序数列, 我们首先检查是否有序, 如果有问题直接\(return\). 然后扫描每个块, 每两个块都必须是有序的, 否则要交换. 如果\(tot \geqslant 4\)那么一定不合法. 代码表达的非常清楚.
Code
#include <algorithm>
#include <cstdio>
#define ll long long
const int maxn = 1 << 13;
int n;
int a[maxn];
ll po[13];
ll ans;
bool check(int k) {
for (int i = 1; i <= (1 << (n - k)); i++)
if (a[(i - 1) * (1 << k) + 1] + (1 << (k - 1)) !=
a[(i - 1) * (1 << k) + (1 << (k - 1)) + 1])
return 0;
return 1;
}
void swap(int i, int j, int k) {
for (int m = 1; m <= k; m++)
std::swap(a[i + m - 1], a[j + m - 1]);
}
void dfs(int now, int num) {
if (now && !check(now))
return;
if (now == n) {
ans += po[num];
return;
}
dfs(now + 1, num);
int tmp[5], tot = 0;
for (int i = 1; i <= (1 << (n - now)); i += 2)
if (a[i * (1 << now) + 1] != a[(i - 1) * (1 << now) + 1] + (1 << now)) {
if (tot == 4)
return;
tmp[++tot] = i;
tmp[++tot] = i + 1;
}
if (!tot)
return;
for (int i = 1; i <= tot; i++)
for (int j = i + 1; j <= tot; j++) {
swap((1 << now) * (tmp[i] - 1) + 1, (1 << now) * (tmp[j] - 1) + 1,
1 << now);
dfs(now + 1, num + 1);
swap((1 << now) * (tmp[i] - 1) + 1, (1 << now) * (tmp[j] - 1) + 1,
1 << now);
}
}
int main() {
// freopen("input", "r", stdin);
po[0] = 1;
for (int i = 1; i <= 12; i++)
po[i] = po[i - 1] * i;
scanf("%d", &n);
for (int i = 1; i <= 1 << n; i++)
scanf("%d", &a[i]);
dfs(0, 0);
printf("%lld", ans);
}
[bzoj3990][SDOI2015]排序-搜索的更多相关文章
- BZOJ 3990: [SDOI2015]排序 [搜索]
3990: [SDOI2015]排序 题意:\(2^n\)的一个排列,给你n种操作,第i种把每\(2^{i-1}\)个数看成一段,交换任意两段.问是这个序列有序的操作方案数,两个操作序列不同,当且仅当 ...
- [BZOJ3990][SDOI2015]排序(DFS)
3990: [SDOI2015]排序 Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 902 Solved: 463[Submit][Status][ ...
- [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]排序
Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 651 Solved: 338 Description 小A有一个1-2^N的排列A[1..2^N], ...
- BZOJ 3990 [SDOI2015]排序 ——搜索
[题目分析] 可以发现,操作的先后顺序是不影响结果的,那么答案就是n!的和. 可以从小的步骤开始搜索,使得每一个当前最小的块都是上升的数列,然后看看是否可行即可. 复杂度好像是4^n [代码](哪里写 ...
- BZOJ 3990: [SDOI2015]排序(搜索+剪枝)
[SDOI2015]排序 Description 小A有一个1-2^N的排列A[1..2^N],他希望将A数组从小到大排序,小A可以执行的操作有N种,每种操作最多可以执行一次,对于所有的i(1< ...
- 006-筛选分类排序搜索查找Filter-Classificatio-Sort-Search-Find-Seek-Locate
006-筛选分类排序搜索查找Filter-Classificatio-Sort-Search-Find-Seek-Locate https://www.cnblogs.com/delphixx/p/1 ...
- 【LG3322】[SDOI2015]排序
[LG3322][SDOI2015]排序 题面 洛谷 题解 交换顺序显然不影响答案,所以每种本质不同的方案就给答案贡献次数的阶乘. 从小往大的交换每次至多\(4\)中决策,复杂度\(O(4^n)\). ...
随机推荐
- 「日常训练」「小专题·图论」Domino Effect(1-5)
题意 分析 这题几乎就是一条dijkstra的问题.但是,如何考虑倒在中间? 要意识到这题求什么:单源最短路的最大值.那么有没有更大的?倒在中间有可能会使它更大. 但是要注意一个问题:不要把不存在的边 ...
- APP功能性测试-4
弱网络测试 使用fiddler模拟低速环境 使用fiddler抓取手机上某个应用的包 手机连接fiddler fiddler 代理地址127.0.0.1默认端口8888 只抓http协议(https, ...
- Python第二天 (数据类型,变量 )
1. 把任意数据类型赋值给变量 在Python中,等号=是赋值语句,可以把任意数据类型赋值给变量,同一个变量可以反复赋值,而且可以是不同类型的变量,例如: 例子:a = 123 # a是整数 prin ...
- Python 把两个列表遍历为一个
两个list, 有对应关系,希望同时完成遍历 用迭代器迭代的方法也不是不可以,python提供了更直观的方法: 可以使用zip把两个list打包 , 类似: list1 = [1,2,3,4] lis ...
- HDU 3698 Let the light guide us(DP+线段树)(2010 Asia Fuzhou Regional Contest)
Description Plain of despair was once an ancient battlefield where those brave spirits had rested in ...
- IDE API SDK JDK
一.IDE 英文全称:Integrated Development Environment 中文名称:集成开发环境 本质:应用程序 功能:提供程序开发环境 组成:代码编辑器.编译器.调试器.图形用户界 ...
- 轻量级权限管理系统——MVC基础
Microsoft Web 开发平台
- HDU 2131 Probability
http://acm.hdu.edu.cn/showproblem.php?pid=2131 Problem Description Mickey is interested in probabili ...
- 在 Linux 安装 JDK 和 tomcat(菜鸡级别)
安装JDK 卸载 OPENJDK rpm -qa|grep jdk // 查看当前的jdk情况 yum -y remove java java-1.7.0-openjdk* // 卸载openjdk ...
- 用WebService实现两个整数运算
最近,项目开发中需要用到Web Service.自己在网上搜集资料.自己做了一个小例子,用来加深自己对Web Service理解. 概念:Web Service主要是为了使原来各孤立的站点之间的信息能 ...