给你一个长度为n(n<=9)的序列,每次可以将一段连续的子序列剪切到其他地方,问最少多少次操作能将序列变成升序。

本题最大的坑点在于让人很容易想到许多感觉挺正确但实际却不正确的策略来避开一些看似“不好”的操作,比如:不破坏连续的片段,拼接时总是保证多出一个比它左边的数大一的数,等等。而实际上这些策略都是错误的,所以只能暴搜。“将一段连续的子序列剪切到其他地方”等价于“交换两段连续的片段”,因此可以枚举三个划分点i,j,k进行搜索,但这样的话dfs树会很宽大,会TLE。考虑到最少只需要n-1步就能完成任务,因此可以用IDA*来优化,设估价函数h代表当前序列中不正确的数的个数,则每次操作最多将h减少3,用这个来剪枝。

“交换片段”的操作的分界点的选取是个难点,如果自己边界处理的能力不够好的话,不断调参去试也不失为一个好的方法(人体模拟退火)。此外,也可以用C++的库函数copy来简化代码。

 #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=+;
int a[N],b[N],n,ka;
int calh() {
int ret=;
for(int i=; i<n-; ++i)if(a[i]+!=a[i+])ret++;
if(a[n-]!=n)ret++;
return ret;
} void cut(int l,int m,int r) {
copy(a+m,a+r,b);
copy(a+l,a+m,b+(r-m));
copy(b,b+(r-l),a+l);
} bool dfs(int dep,int mxd) {
int h=calh();
if(h==)return ;
if(*dep+h>*mxd)return ;
for(int i=; i<n; ++i)
for(int k=i+; k<=n; ++k)
for(int j=i+; j<k; ++j) {
cut(i,j,k);
if(dfs(dep+,mxd))return ;
cut(i,i+(k-j),k);
}
return ;
} int IDAStar() {for(int mxd=;; ++mxd)if(dfs(,mxd))return mxd;} int main() {
while(scanf("%d",&n)&&n) {
printf("Case %d: ",++ka);
for(int i=; i<n; ++i)scanf("%d",&a[i]);
printf("%d\n",IDAStar());
}
return ;
}

UVA - 11212 Editing a Book (IDA*)的更多相关文章

  1. UVa 11212 Editing a Book (IDA* && 状态空间搜索)

    题意:你有一篇n(2≤n≤9)个自然段组成的文章,希望将它们排列成1,2,…,n.可以用Ctrl+X(剪切)和Ctrl+V(粘贴)快捷键来完成任务.每次可以剪切一段连续的自然段,粘贴时按照顺序粘贴.注 ...

  2. UVA 11212 Editing a Book [迭代加深搜索IDA*]

    11212 Editing a Book You have n equal-length paragraphs numbered 1 to n. Now you want to arrange the ...

  3. UVA - 11212 Editing a Book (IDA*搜索)

    题目: 给出n(1<n<10)个数字组成的序列,每次操作可以选取一段连续的区间将这个区间之中的数字放到其他任意位置.问最少经过多少次操作可将序列变为1,2,3……n. 思路: 利用IDA* ...

  4. UVA - 11212 Editing a Book(IDA*算法+状态空间搜索)

    题意:通过剪切粘贴操作,将n个自然段组成的文章,排列成1,2,……,n.剪贴板只有一个,问需要完成多少次剪切粘贴操作可以使文章自然段有序排列. 分析: 1.IDA*搜索:maxn是dfs的层数上限,若 ...

  5. uva 11212 - Editing a Book(迭代加深搜索 IDA*) 迭代加深搜索

    迭代加深搜索 自己看的时候第一遍更本就看不懂..是非常水,但智商捉急也是没有办法的事情. 好在有几个同学已经是做过了这道题而且对迭代加深搜索的思路有了一定的了解,所以在某些不理解的地方询问了一下他们的 ...

  6. UVA 11212 Editing a Book

    题意: 有一篇由n个自然段组成的文章.希望将他们排成递增序列.只能剪贴和粘贴交替进行,剪贴时可以剪贴一段连续的自然段. 分析: 用IDA*算法求解.当3*d+h>maxd时剪枝. 代码: #in ...

  7. Editing a Book UVA - 11212 IDA*

    You have n equal-length paragraphs numbered 1 to n . Now you want to arrange them in the order of 1 ...

  8. 【UVa】11212 Editing a Book(IDA*)

    题目 题目     分析 get一下IDA*的技巧,感觉总体来说不难,主要是剪枝比较难想. 这是lrj的代码,比较通俗易懂,关键就是选定一个区间再取出来,插入到一个位置,接下来转移到这个状态.     ...

  9. UVA 11212 IDA*

    移动一块连续的区间使得数列递增.问最少次数. 直接IDA*暴搜,只是我没有想到A*函数,所以就随手写了个连续递增块数作为估价函数,WA了,然后除以2,还是WA,除以3,WA,除以4...过了= = # ...

随机推荐

  1. requirejs源码分析: define 方法

    define = function (name, deps, callback) {     var node, context; //Allow for anonymous modules     ...

  2. SpringMVC:学习笔记(4)——处理模型数据

    SpringMVC—处理模型数据 说明 SpringMVC 提供了以下几种途径输出模型数据: – ModelAndView: 处理方法返回值类型为 ModelAndView时, 方法体即可通过该对象添 ...

  3. 深度学习2--安装opencv3.1

    1\opencv的安装参考视频 2\ 以下内容来自:http://blog.csdn.net/l18930738887/article/details/54696148 本人因为被坑过,所以建议各位最 ...

  4. Linux基本命令 vim命令(二)

    Linux Vim显示行号 在命令模式下输入" : " 进入编辑模式后执行 set nu 命令 即可显示每一行的行号,如果想要取消行号,则再次输入":set nonu&q ...

  5. 释放Linux系统缓存

    清理Linux缓存使用下面的命令 sync; echo 3 > /proc/sys/vm/drop_caches 需求与原理 下面介绍buffer与cache的差别: A buffer is s ...

  6. React Native的生命周期解析

    在React Native中使用组件来封装界面模块时,整个界面就是一个大的组件,开发过程就是不断优化和拆分界面组件.构造整个组件树的过程. 上张图涵盖了一个组件从创建.运行到销毁的整个过程.大家可以看 ...

  7. iOS_UIAlertController

    ViewController.m文件 #import "ViewController.h" @interface ViewController () // @property (n ...

  8. python里两种遍历目录的方法

    os.walk 函数声明:os.walk(top,topdown=True,onerror=None) (1)参数top表示需要遍历的顶级目录的路径. (2)参数topdown的默认值是“True”表 ...

  9. 同类型元素,只有一个被选中js

    <div class="wrap-box flex_row"> <div class="wrap-block"> <div cla ...

  10. mybaties mapping中if

    mapping中 if的简单使用 <insert id="addPassenger" resultMap="EmpResultMap" parameter ...