【BZOJ3990】排序(SDOI2015)-DFS+贪心
来源:互联网 发布:淘宝怎么微信零钱支付 编辑:程序博客网 时间:2024/06/03 17:12
测试地址:排序
做法:首先我们知道,如果存在一个长度为k的可行操作序列(就是用了k个操作使原数列排好序),将它操作的顺序随意变换都是一个可行的序列,那么其对答案的贡献为k!。于是我们从小到大搜索操作,当搜索到第i种操作时,表示我们已经处理完前i-1种操作了。将原数列分成2^i个元素一块,判断每个块是否合法,一个块合法当且仅当块中的元素连续且递增。可以证明,操作做在合法的块中是没有意义的,所以我们分析,如果只有一个块不合法,那么则将这一块的左半部分和右半部分互换,再检查这个块是否变得合法,如果合法则继续搜索。如果有两个块不合法,那么尝试调换第一块的左右部分的其中一个和第二块的左右部分的其中一个,分为4种情况,对于每种情况再检查两个块是否变得合法,如果合法则继续搜索。如果有三个以上的块不合法则无解。最后在细节上再多注意即可。
以下是本人代码:
#include <cstdio>#include <cstdlib>#include <iostream>#include <algorithm>using namespace std;int num[5010],fac[20],ans=0;int n;bool check(int s,int pos){ s=((s-1)<<pos)+1; int last=num[s]; for(int i=2;i<=(1<<pos);i++) { if (num[s+i-1]!=last+1) return 0; else last=num[s+i-1]; } return 1;}void Swap(int s1,int s2,int pos){ for(int i=1;i<=(1<<pos);i++) swap(num[s1+i-1],num[s2+i-1]);}void dfs(int pos,int k){ if (pos==n+1) {ans+=fac[k];return;} int p1=0,p2=0; for(int i=1;i<=(1<<(n-pos));i++) {if (!check(i,pos)){ if (!p1) p1=i; else if (!p2) p2=i; else return;} } if (!p1&&!p2) dfs(pos+1,k); else if (p1&&!p2) { Swap(((p1-1)<<pos)+1,((p1-1)<<pos)+(1<<(pos-1))+1,pos-1);if (check(p1,pos)) dfs(pos+1,k+1);Swap(((p1-1)<<pos)+1,((p1-1)<<pos)+(1<<(pos-1))+1,pos-1); } else { for(int a=0;a<=1;a++) for(int b=0;b<=1;b++) {int s1,s2; if (!a) s1=((p1-1)<<pos)+1;else s1=((p1-1)<<pos)+(1<<(pos-1))+1;if (!b) s2=((p2-1)<<pos)+1;else s2=((p2-1)<<pos)+(1<<(pos-1))+1;Swap(s1,s2,pos-1);if (check(p1,pos)&&check(p2,pos)) dfs(pos+1,k+1);Swap(s1,s2,pos-1); } }}int main(){ scanf("%d",&n); fac[0]=1; for(int i=1;i<=n;i++) fac[i]=fac[i-1]*i; for(int i=1;i<=(1<<n);i++) scanf("%d",&num[i]); dfs(1,0); printf("%d",ans); return 0;}
0 0
- 【BZOJ3990】排序(SDOI2015)-DFS+贪心
- 【bzoj3990】[SDOI2015]排序 DFS
- 【bzoj3990】【SDOI2015】【排序】【dfs】
- bzoj3990 [SDOI2015]排序 dfs
- 【bzoj3990】 SDOI2015排序 dfs搜索+剪枝
- 【SDOI2015】【BZOJ3990】排序
- bzoj3990【SDOI2015】排序
- 【SDOI2015】bzoj3990 排序
- bzoj3990: [SDOI2015]排序
- 【BZOJ3990】【SDOI2015】排序
- [bzoj3990][SDOI2015]排序 搜索
- 【BZOJ3990】【SDOI2015】排序
- BZOJ 3990 Sdoi2015 排序 DFS
- bzoj 3990: [SDOI2015]排序 dfs
- [BZOJ3991][SDOI2015]寻宝游戏(dfs序+lca+set)
- bzoj3991 [SDOI2015]寻宝游戏 (虚树+set+dfs序 )
- [BZOJ3991][SDOI2015]寻宝游戏(dfs序+set/平衡树)
- codeforces_622E. Ants in Leaves(dfs+排序+贪心)
- c++学习笔记--由复数类看运算符重载
- 【Hihocoder [Offer收割]编程练习赛10 A】【水题】出勤记录I
- PHP Socket 编程
- Zookeeper分布式锁的简单实现
- eclipse快捷键大全
- 【BZOJ3990】排序(SDOI2015)-DFS+贪心
- 和为s的两个数字
- 使用AJAX技术实现网页部分信息的更新
- nginx 服务器重启关闭重新加载
- Git学习总结
- libgomp.so.1: version `GOMP_4.0' not found 解决办法
- 5-9 集合相似度 (set的运用)
- 网页制作中遇到的一些问题及解决方案
- Qt 的QString类的使用