题意:通过剪切粘贴操作,将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. 新闻网大数据实时分析可视化系统项目——8、Flume数据采集准备

    Flume是Cloudera提供的一个高可用的,高可靠的,分布式的海量日志采集.聚合和传输的系统,Flume支持在日志系统中定制各类数据发送方,用于收集数据:同时,Flume提供对数据进行简单处理,并 ...

  2. 配置<welcome-file>直接访问请求

    方法一.配置welcome-file-list和servlet-mapping <!-- 将默认欢迎页配置为要访问的controller路径 --><welcome-file-lis ...

  3. struts2--通配符映射

    1.通配符映射: --规则: > 1)若找到多个匹配,没有通配符的优先: > 2)若指定动作不存在,struts2将会尝试把这个URI与任何一个包含着通配符*的动作名进行匹配: > ...

  4. ch13 事件(思维导图)

  5. IP、TCP、DNS

    负责传输的IP协议 按层次分,IP网际协议位于网络层.几乎所有使用网络的系统都会用到 IP 协议. “IP”和“IP地址不同”,“IP”是一种协议的名称.IP 协议的作用是把各种数据包传送给对方.而要 ...

  6. 6、mysql事务

    1.mysql事务 —mysql中,事务其实是一个最小的不可分割的工作单元.事务能够保证一个业务的完整性,例如:银行存款: a  - >    -100 >update user set ...

  7. 学习进度-10 python爬虫

    学习爬虫的第一个案例是小说爬虫. 小说爬虫首先是解析小说页面源代码,在页面源代码中可以看到小说每章节的内容链接 爬虫的代码: import requests import re url = 'http ...

  8. POJ 3349:Snowflake Snow Snowflakes 六片雪花找相同的 哈希

    Snowflake Snow Snowflakes Time Limit: 4000MS   Memory Limit: 65536K Total Submissions: 35642   Accep ...

  9. crackme---攻防世界

    首先下载附件之后,查壳 虽然什么也没有发现,但是看一下区段就知道,这个是北斗的壳.所以我们首先载入od开始把壳脱掉 这里面也可以看到pushfd和pushad是北斗壳的特征 这里面我使用是esp定律脱 ...

  10. git 的那点东西,随心记

    目前常用的项目版本管理,协同开发的工具有SVN和GIT,本次就记录一下GIT的基本使用. git下载地址:https://git-scm.com/downloads *根据自己的操作系统进行选择(这里 ...