https://vjudge.net/problem/UVA-11212

题意:给出n个自然段组成的文章,将他们排列成1,2...,n。每次只能剪切一段连续的自然段,粘贴时按照顺序粘贴。

思路:状态空间的搜索问题。

首先介绍一下IDA*,它属于DFS,在DFS遍历的时候,设定一个深度上限maxd,当前结点n的深度为g(n),乐观估价函数为h(n),则当g(n)+h(n)>maxd时应           该剪枝。这样的算法就是IDA*。

在这道题目中,由于最多就9个数,所以最多只需要剪切8次肯定是可以完成升序排列的。所以最大深度可以从1开始一直到8,依次去寻找是否能成功。

在这题中最重要的剪枝就是考虑后继不正确的数字个数h,可以证明每次剪切时h最多减少3,因此如果3*(maxd-d)<h,则可以直接剪枝。因为此时即使一直遍历到限定深         度maxd,也无法将h的个数减为0。另外也还有许多地方可以剪枝,下面的代码中我有仔细介绍。

 #include<iostream>
#include<string>
#include<cstring>
using namespace std; int n;
int a[]; bool goal() //判断是否已达到最终状态
{
for (int i = ; i < n - ; i++)
{
if (a[i]>a[i + ]) return false;
}
return true;
} int h() //计算后继不正确的个数
{
int number = ;
for (int i = ; i < n-; i++)
{
if (a[i + ] != a[i] + )
number++;
}
if (a[n - ] != n) number++;
return number;
} bool dfs(int d, int maxd)
{
if ( * d + h()> * maxd) return false; //剪枝
if (goal()) return true;
int pre[]; //保存原来序列
int cut[]; //保存剪切后的序列
for (int i = ; i < n; i++) //枚举,i为剪切起点,j为剪切终点
{
if (i == || a[i] != a[i - ]+) //剪枝,不破坏连续的数字片段
{
for (int j = i; j < n; j++)
{
while (a[j + ] == a[j] + ) j++; //剪枝,如果一个数字片段已经连续,则不要去破坏它
memcpy(pre, a, sizeof(a));
int cnt = ;
for (int k = ; k < n; k++) //保存剪切后的序号
{
if (k<i || k>j)
cut[cnt++] = a[k];
}
for (int k = ; k <= cnt; k++) //枚举,依次插入到第k个位置之前
{
int cnt2 = ;
for (int t = ; t < k; t++) a[cnt2++] = cut[t];
for (int t = i; t <= j; t++) a[cnt2++] = pre[t];
for (int t = k; t < cnt; t++) a[cnt2++] = cut[t];
if (dfs(d + , maxd)) return true; //继续深搜
memcpy(a, pre, sizeof(pre)); //如果失败,则恢复a[]的原来的数字片段
}
}
}
}
return false;
} int solve()
{
if (goal()) return ;
for (int i = ; i < ; i++) //最多只需要进行8次dfs即可获得最终状态
{
if (dfs(, i)) return i;
}
} int main()
{
//freopen("D:\\txt.txt", "r", stdin);
int kase = ;
while (cin >> n && n)
{
memset(a, , sizeof(a));
for (int i = ; i < n; i++)
cin >> a[i];
int ans=solve();
cout << "Case " << ++kase << ": " << ans << endl;
}
}

UVa 11212 编辑书稿(dfs+IDA*)的更多相关文章

  1. Uva 11212 编辑书稿(迭代加深搜索)

    题意: 给定N个数的序列, 希望将它排列成1~N, 可以用剪切.粘贴来完成任务, 每次可以剪切一段连续的自然段, 粘贴时按照顺序粘贴. #include <bits/stdc++.h> # ...

  2. UVA - 11212 Editing a Book (IDA*)

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

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

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

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

  5. UVA - 11853 Paintball(dfs)

    UVA - 11853 思路:dfs,从最上面超过上边界的圆开始搜索,看能不能搜到最下面超过下边界的圆. 代码: #include<bits/stdc++.h> using namespa ...

  6. UVA.548 Tree(二叉树 DFS)

    UVA.548 Tree(二叉树 DFS) 题意分析 给出一棵树的中序遍历和后序遍历,从所有叶子节点中找到一个使得其到根节点的权值最小.若有多个,输出叶子节点本身权值小的那个节点. 先递归建树,然后D ...

  7. UVA 11212 IDA*

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

  8. UVa 1374 快速幂计算(dfs+IDA*)

    https://vjudge.net/problem/UVA-1374 题意:给出n,计算最少需要几次能让x成为x^n(x和已经生成的数相乘或相除). 思路:IDA*算法. 如果当前数组中最大的数乘以 ...

  9. UVa 1343 旋转游戏(dfs+IDA*)

    https://vjudge.net/problem/UVA-1343 题意:如图所示,一共有8个1,8个2和8个3,如何以最少的移动来使得中间8个格子都为同一个数. 思路:状态空间搜索问题. 用ID ...

随机推荐

  1. display:table和display:table-cell结合使用

    .GoodList{ display :table; height :54px; width :56px; line-height: 14px                 padding: 0 1 ...

  2. jmeter 逻辑控制器Logic Controller详解

    Jmeter之逻辑控制器(Logic Controller) 前言: 1. Jmeter官网对逻辑控制器的解释是:“Logic Controllers determine the order in w ...

  3. 集成学习ensemble

    集成学习里面在不知道g的情况下边学习边融合有两大派:Bagging和Boosting,每一派都有其代表性算法,这里给出一个大纲. 先来说下Bagging和Boosting之间的相同点:都是不知道g,和 ...

  4. 深入浅出TCP之listen

    原文:http://blog.chinaunix.net/uid-29075379-id-3858844.html int listen(int fd, int backlog); 有几个概念需要在开 ...

  5. 在liferay中如何使用Ajax的请求

    1:首先在界面上写一个路径,这个路径就是要找后台中的哪一个操作比如:

  6. 一款优秀的OA办公系统有哪些功能?

    OA办公系统解决企业的日常管理规范化.增加企业的可控性.提高企业运转的效率的基本问题,范围涉及日常行政管理.各种事项的审批.办公资源的管理.多人多部门的协同办公.以及各种信息的沟通与传递.可以概括的说 ...

  7. uva10905

    /* 很好的字符串 比较方法 很多个字符串 组成的 数字 需要最大 然后 比较 a和b 是 比较a+b 和b+a 的大小 */ #include<cstdio> #include<s ...

  8. Java缓存学习之六:Spring单独使用EhCache

      通过在Application Context中配置EhCacheManagerFactoryBean和EhCacheFactoryBean,我们就可以把对应的EhCache的CacheManage ...

  9. linux常用命令:traceroute 命令

    通过traceroute我们可以知道信息从你的计算机到互联网另一端的主机是走的什么路径.当然每次数据包由某一同样的出发点(source)到达某一同样的目的地(destination)走的路径可能会不一 ...

  10. Python中的is和==的区别,==判断值是否相等,is判断地址是否一致

    Python中的is和==的区别 Python中的对象包含三要素:id.type.value. 其中id用来唯一标示一个对象,type标识对象的类型,value是对象的值. is判断的是a对象是否就是 ...