UVA - 11212 Editing a Book(IDA*算法+状态空间搜索)
题意:通过剪切粘贴操作,将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*算法+状态空间搜索)的更多相关文章
- UVa 11212 Editing a Book (IDA* && 状态空间搜索)
题意:你有一篇n(2≤n≤9)个自然段组成的文章,希望将它们排列成1,2,…,n.可以用Ctrl+X(剪切)和Ctrl+V(粘贴)快捷键来完成任务.每次可以剪切一段连续的自然段,粘贴时按照顺序粘贴.注 ...
- UVA - 11212 Editing a Book (IDA*)
给你一个长度为n(n<=9)的序列,每次可以将一段连续的子序列剪切到其他地方,问最少多少次操作能将序列变成升序. 本题最大的坑点在于让人很容易想到许多感觉挺正确但实际却不正确的策略来避开一些看似 ...
- 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 ...
- UVA 11212 Editing a Book
题意: 有一篇由n个自然段组成的文章.希望将他们排成递增序列.只能剪贴和粘贴交替进行,剪贴时可以剪贴一段连续的自然段. 分析: 用IDA*算法求解.当3*d+h>maxd时剪枝. 代码: #in ...
- UVA - 11212 Editing a Book (IDA*搜索)
题目: 给出n(1<n<10)个数字组成的序列,每次操作可以选取一段连续的区间将这个区间之中的数字放到其他任意位置.问最少经过多少次操作可将序列变为1,2,3……n. 思路: 利用IDA* ...
- uva 11212 - Editing a Book(迭代加深搜索 IDA*) 迭代加深搜索
迭代加深搜索 自己看的时候第一遍更本就看不懂..是非常水,但智商捉急也是没有办法的事情. 好在有几个同学已经是做过了这道题而且对迭代加深搜索的思路有了一定的了解,所以在某些不理解的地方询问了一下他们的 ...
- 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 ...
- UVa 1343 The Rotation Game (状态空间搜索 && IDA*)
题意:有个#字型的棋盘,2行2列,一共24个格. 如图:每个格子是1或2或3,一共8个1,8个2,8个3. 有A~H一共8种合法操作,比如A代表把A这一列向上移动一个,最上面的格会补到最下面. 求:使 ...
- UVa 1374 Power Calculus (IDA*或都打表)
题意:给定一个数n,让你求从1至少要做多少次乘除才可以从 x 得到 xn. 析:首先这个是幂级的,次数不会很多,所以可以考虑IDA*算法,这个算法并不难,难在找乐观函数h(x), 这个题乐观函数可以是 ...
随机推荐
- rsa免密钥登陆
#第一步 生成密钥,一路回车就行 ssh-keygen -t rsa #第二步 将密钥拷贝到目标服务器上,注意双引号 ssh-copy-id -i ~/.ssh/id_rsa.pub "ro ...
- java文件相关(文件追加内容、文件内容清空、文件内容读取)
https://blog.csdn.net/xnz0616/article/details/39137177 1.文件内容追加 // 在已有的文件后面追加信息 public static void a ...
- docker-lnmp 多容器部署 Laravel 方案分享(转)
docker lnmp 多容器部署方案.完全基于 docker 官方镜像,遵循最佳实践,一容器一进程. github 项目地址 https://github.com/March7/docker-lnm ...
- when_did_you_born-瞟来的wp
继上文,这次开始嫖when_did_you_born这题.前面的步骤大致是一样的就不赘述了,直接到代码分析. 字符串 这次呢在main函数处 按下F5进入调试 查看反汇编代码 可以清楚的看到它的逻辑一 ...
- 如何让Dev支持c++11特性
1.点击工具选择编译选项 2.在编译时加入以下命令点击之后再将-std=c++11加入,点击确定就ok了
- Tcp 3次握手 4次挥手
Tcp 3次握手 4次挥手 标签(空格分隔): Java基础 报文介绍: SYN(synchronous建立联机) ACK(acknowledgement 确认) FIN(finish结束) PSH( ...
- leetcode349 350 Intersection of Two Arrays & II
""" Intersection of Two Arrays Given two arrays, write a function to compute their in ...
- YOKOGAWA ProSafe-RS 通道测试 CENTUMVP
20180927 我并没有调试这个项目 仅仅是听同事讲解了 横河ProSafe-RS通道测试 然后做了笔记 软件安装并不在本记录中 ProSafe-RS版本 CENTUMVP版本 ProSafe-RS ...
- python数据分析基础
---恢复内容开始--- Python数据分析基础(1) //2019.07.09python数据分析基础总结1.python数据分析主要使用IDE是Pycharm和Anaconda,最为常用和方便的 ...
- 解决oracle 11g 导出空表的方法
ORACLE 11G中有个新特性,当表无数据时,不分配segment,以节省空间. 解决方法: 1)insert一行,再rollback就产生segment了 该方法是在在空表中插入数据,再删除,则产 ...