题意:通过剪切粘贴操作,将n个自然段组成的文章,排列成1,2,……,n。剪贴板只有一个,问需要完成多少次剪切粘贴操作可以使文章自然段有序排列。

分析:

1、IDA*搜索:maxn是dfs的层数上限,若在maxn范围内未找到解,则++maxn,直到找到解。对于每个当前深度deep,若还需要搜索m层才能找到解,而deep+m>maxn,则剪枝。

2、对于本题,选取估价函数,若当前深度下,后继不正确的数字个数是m,则还需要m/3层才能找到解。即若deep+m/3>maxn则剪枝。

3、不断枚举剪切片段,并将其粘贴到后面。

4、剪切区间是一段一段的连续数字,连续数字的长度可为1。

#pragma comment(linker, "/STACK:102400000, 102400000")
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cctype>
#include<cmath>
#include<iostream>
#include<sstream>
#include<iterator>
#include<algorithm>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<stack>
#include<deque>
#include<queue>
#include<list>
#define Min(a, b) ((a < b) ? a : b)
#define Max(a, b) ((a < b) ? b : a)
typedef long long ll;
typedef unsigned long long llu;
const int INT_INF = 0x3f3f3f3f;
const int INT_M_INF = 0x7f7f7f7f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const ll LL_M_INF = 0x7f7f7f7f7f7f7f7f;
const int dr[] = {, , -, , -, -, , };
const int dc[] = {-, , , , -, , -, };
const int MOD = 1e9 + ;
const double pi = acos(-1.0);
const double eps = 1e-;
const int MAXN = 1e5 + ;
const int MAXT = + ;
using namespace std;
int a[];
int maxn;
int n;
bool judge(){//自然段是否有序排列
for(int i = ; i < n; ++i){
if(a[i - ] > a[i]) return false;
}
return true;
}
int getCount(){//后继不正确的数字个数
int cnt = ;
for(int i = ; i < n; ++i){
if(a[i - ] + != a[i]) ++cnt;
}
return cnt;
}
bool dfs(int deep){//当前深度
if( * deep + getCount() > * maxn) return false;//剪枝
if(judge()) return true;
int save[];//暂存a数组,便于恢复数组a
int cut[];
memcpy(save, a, sizeof(a));//save暂存a
for(int i = ; i < n; ++i){//枚举剪切起点
if(!i || a[i - ] + != a[i]){//剪切起点
for(int j = i; j < n; ++j){//枚举剪切终点
while(j + < n && a[j] + == a[j + ]) ++j;//当前的j为剪切区间的终点,剪切保证永远不要“破坏”一个已经连续排列的数字片段
memcpy(cut, save + i, sizeof (int) * (j - i + ));//剪切区间放在cut里
for(int k = j + ; k < n; ++k){//枚举粘贴起点
while(k + < n && a[k] + == a[k + ]) ++k;//粘贴起点保证不破坏连续排列的数字片段,k为最后确定的粘贴起点
memcpy(a + i, save + j + , sizeof(int) * (k - j));
memcpy(a + i + k - j, cut, sizeof(int) * (j - i + ));//这两步完成了将剪切片段粘贴到下标k后面
if(dfs(deep + )) return true;
memcpy(a, save, sizeof(a));//sizeof(a)是数组a所占内存的长度,该修改不成立,恢复数组a
}
}//剪切区间是一段一段的连续数字,连续数字的长度可为1
}
}
return false;//所有剪切粘贴情况都不成立
}
int solve(){
if(judge()) return ;//不需要剪切粘贴
for(maxn = ; ; ++maxn){//枚举深度
if(dfs()) return maxn;
}
}
int main(){
int kase = ;
while(scanf("%d", &n) == ){
if(!n) return ;
for(int i = ; i < n; ++i){
scanf("%d", a + i);
}
int ans = solve();
printf("Case %d: %d\n", ++kase, ans);
}
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*)

    给你一个长度为n(n<=9)的序列,每次可以将一段连续的子序列剪切到其他地方,问最少多少次操作能将序列变成升序. 本题最大的坑点在于让人很容易想到许多感觉挺正确但实际却不正确的策略来避开一些看似 ...

  3. 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 ...

  4. UVA 11212 Editing a Book

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

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

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

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

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

  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 1343 The Rotation Game (状态空间搜索 && IDA*)

    题意:有个#字型的棋盘,2行2列,一共24个格. 如图:每个格子是1或2或3,一共8个1,8个2,8个3. 有A~H一共8种合法操作,比如A代表把A这一列向上移动一个,最上面的格会补到最下面. 求:使 ...

  9. UVa 1374 Power Calculus (IDA*或都打表)

    题意:给定一个数n,让你求从1至少要做多少次乘除才可以从 x 得到 xn. 析:首先这个是幂级的,次数不会很多,所以可以考虑IDA*算法,这个算法并不难,难在找乐观函数h(x), 这个题乐观函数可以是 ...

随机推荐

  1. 094、Java中String类之直接赋值时的堆内存自动引用

    01.代码如下: package TIANPAN; /** * 此处为文档注释 * * @author 田攀 微信382477247 */ public class TestDemo { public ...

  2. centos7下安装JDK1.8

    步骤1:Oracle下载jdk-8u141-linux-x64安装包 步骤2:解压jdk-8u141-linux-x64.tar.gz到home目录 [root@model ~]# tar -zxvf ...

  3. less在vscode中的配置方式

    1.在vscode插件中下载easy less这个插件. 2.新建项目,分别建两个文件夹存放less和自动编译好的css,页面中引入文件引css就可以了. 3.根据你的文件位置,在用户设置中设置需要配 ...

  4. Unity Scene视图下 输出物体坐标等信息

    using UnityEditor; using UnityEngine; [CustomEditor(typeof(GameObject))] public class MyEditor : Edi ...

  5. 一、Linux&配置,依赖安装&Tomcat,Mysql,jdk安装

    基础知识: 1 OS Operation System 作用:控制硬件,服务软件 2 VMware虚拟机: 虚拟出一台计算机环境 配置两个虚拟网卡,适配器里查看 3 在虚拟机上安装操作系统Linux ...

  6. mysql多实例双主部署

    本文引自公司技术文档,仅作为记录. 背景 有的时候需要进行数据库环境的隔离,以及节省服务器资源一台mysql安装多个数据库实例,一个实例下构建多个数据库​ 安装mysql yum -y install ...

  7. 洛谷 P4391 [BOI2009]Radio Transmission 无线传输

    题目传送门 解题思路: 本题所要求的循环节,其实就是最长公共前缀的前缀长度减去前后缀重叠的一部分 AC代码: #include<iostream> #include<cstdio&g ...

  8. Flutter Web环境搭建

    接上篇Flutter Windows下AndroidStudio环境搭建 1.https://github.com/flutter/flutter_web 下载放到本地路径下 2.系统Path增加(根 ...

  9. 【WPF学习】第二十二章 文本控件

    WPF提供了三个用于输入文本的控件:TextBox.RichTextBox和PasswordBox.PasswordBox控件直接继承自Control类.TextBox和RichTextBox控件间接 ...

  10. notifix测试

    成功 失败 警告 提示