题意:

给定N个数的序列, 希望将它排列成1~N, 可以用剪切、粘贴来完成任务, 每次可以剪切一段连续的自然段, 粘贴时按照顺序粘贴。

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i = a; i < b; i++)
#define _rep(i,a,b) for(int i = a; i <= b; i++)
using namespace std;
const int maxn = ;
int n, maxd;
int p[maxn], ans;
int h(){//统计每个元素后继不符合的个数, 最后一个特判是否为N
int cnt = ;
rep(i,,n-) if(p[i+] != p[i] + ) cnt++;
if(p[n-] != n) cnt++;
return cnt;
} bool dfs(int d){
if(d* + h() > maxd*) return false; //由于每次交换最多减少3个后继不符合, 所以当前层数*3 + 上h()大于maxd * 3, 直接剪枝
if(d == maxd){
if(h() == ) return true;
return false;
}
int b[maxn], old[maxn], cnt = ;
memcpy(old,p,sizeof(p));
rep(i,,n) //选择起点
rep(j,i,n) //选择终点 , p上取 3个点, i , j , k
rep(k,j+,n){ //由于具有对称性, 直接把前面换到后面就行
memcpy(b,old+i,sizeof(int) * (j-i+)); //将i~j剪贴的内容复制到b memcpy(p+i,old+j+, sizeof(int) * (k-j));//将i~j 与 (j+1)~k互换
memcpy(p+i+k-j, b, sizeof(int) * (j-i+)); if(dfs(d+)) return true;
memcpy(p,old,sizeof(old));
}
return false;
} int main(){
int kase = ;
while(cin >> n && n){
rep(i,,n) cin >> p[i];
for(maxd = ; maxd <= ; maxd++){ //注意maxd要从0开始, 因为有可能一开始就是有序的
if(dfs()) break;
}
cout << "Case " << ++kase << ": " << maxd << "\n";
}
}

最新文章

  1. 微软开源代码编辑器monaco-editor
  2. vuejs,router
  3. 编写一个make
  4. Jexus web server V5.4.5 已经发布
  5. jenkins 状态管理
  6. linux 学习笔记2
  7. mysql监控管理工具--innotop
  8. Android 解决双卡双待手机解析短信异常
  9. linux0.12 链接过程
  10. AC自动机(AC automation)
  11. (转)Unity3D 之插值计算
  12. MSSQL 常用操作
  13. [Android] Android Error: Suspicious namespace and prefix combination [NamespaceTypo] when I try create Signed APK
  14. &lt;input&gt;标签单、复选相关查询地址
  15. Oracle 泵导入导出
  16. Google Colab 基本操作
  17. WPF应用程序内存泄漏的一些原因
  18. JavaScript 六大类运算符(详细~)
  19. [20171031]markhot.txt
  20. 用flock命令解决Linux计划任务重复执行

热门文章

  1. hud3371 Connect the Cities 简单最小生成树
  2. the little schemer 笔记(1)
  3. 线段树/树状数组 POJ 2182 Lost Cows
  4. selenium处理的操作
  5. LVS实现负载均衡
  6. android开发学习 ------- MongoDB数据库简单理解
  7. 小程序java解密
  8. 基于Java实现的冒泡排序算法
  9. vue安装概要以及vue测试工具
  10. Java长存!12个Java长久占居主要地位的原因