迭代加深搜索算法总结 + Editing a Book UVa11212题解
迭代加深搜索算法:
对于可以用回溯法解决,但是解答树结点数大的恐怖的问题的一种解决办法,有的问题甚至用bfs连一层节点都遍历不完就超时了。具体方法就是依次枚举搜索层数,从1到一个上限。
结构:
int solve() {
for (int maxd = 1; maxd < MAXN; maxd++) {
if (dfs(0, maxd)) return maxd;
}
return MAXN;
}
优点:
相较于bfs老老实实的枚举解答树而言, 迭代加深搜索算法可以以深度优先搜索,也就是说可以第一时间到达最深层次进行搜索。平均时间上而言比bfs逐层搜索要快太多太多了,再配合回溯剪枝。优化效果相当可观!
举例:
UVa11212 Editing a Book
对于这道题, 0 < n < 10, 也就是总状态有9! = 362880个。 虽然看起来很少,但是每个结点可以扩展到的结点个数是 (n * (n/2) * (n/2)) = (n^3)/4 ≈ 183, 再加上对每个结点判重和剪枝计算,每个结点的计算量大概是 183 * 40 = 7290
所以对于一组n = 9的数据,最差情况的计算量是 n! * (n^3)/4 * 40 ≈ 26亿
然而测试数据一共有20组
也就是说 总计算量是 26亿 * 20 = 520亿
即便我用bfs+剪枝, 程序还是毫无悬念的超时了。
然而如果我用迭代加深搜索算法,20组数据运行时间总和是49ms, 快了2000倍!
UVa11212 Editing a Book 迭代加深搜索+剪枝(49ms, Ac)
#include <cstdio>
#include <cstring>
using namespace std; int n, idx, maxd, a[];
bool ok; void create(int start, int len, int k) {
int olda[];
memcpy(olda, a, sizeof(a));
int z = , i = ;
for (; z < k; z++) {
if (z >= start && z < start + len) { z += (len - ); continue;}
a[i++] = olda[z];
}
for (z = ; z < len; z++) a[i++] = olda[start + z];
for (z = k; z < n; z++) {
if (z >= start && z < start + len) { z += (len - ); continue;}
a[i++] = olda[z];
}
} int num_unordered() {
int cnt = ;
for (int i = ; i < n; i++) if (a[i - ] + != a[i]) cnt++;
cnt = cnt ? cnt + : ;
return cnt;
} bool success() {
for (int i = ; i < n - ; i++) if (a[i] + != a[i + ]) return false;
return true;
} bool dfs(int d) {
if (d * + num_unordered() > * maxd) return false;
if (success()) { ok = ; return true;}
int temp[];
memcpy(temp, a, sizeof(a));
for (int i = ; i < n; i++)
for (int j = i + ; j <= n; j++)
for (int k = ; k <= n; k++) {
if (k >= i && k <= j) { k = j; continue;}
create(i, j - i, k);
if (dfs(d + )) return true;
memcpy(a, temp, sizeof(a));
}
return false;
} int solve() {
if (success()) return ;
ok = ;
for (maxd = ; maxd < ; maxd++)
if (dfs()) return maxd;
return maxd;
} int main() {
int T = ;
while (scanf("%d", &n) == && n) {
printf("Case %d: ", ++T);
for (int i = ; i < n; i++) scanf("%d", &a[i]);
int ans = solve();
printf("%d\n", ans);
}
return ;
}
UVa11212 Editing a Book BFS搜索+剪枝 (估计耗时18s)
#include <cstdio>
#include <cstdlib>
#include <queue>
#include <algorithm>
#include <cstring>
using namespace std; const int MAXN = , MAXHASHSIZE = ;
int n, idx, target;
int a[], _head[MAXHASHSIZE], _next[MAXN], st[MAXN]; struct Node {
int arr[], dis, num;
Node (int d = ): dis(d) {}
void trans() {
num = ;
for (int i = ; i < n; i++) {
num *= ;
num += arr[i];
}
}
}; bool try_to_insert(Node &cur) {
int h = cur.num % MAXHASHSIZE;
int u = _head[h];
while (u) {
if (st[u] == cur.num) return false;
u = _next[u];
}
st[idx] = cur.num;
_next[idx] = _head[h];
_head[h] = idx++;
return true;
} void create(Node &from, Node &des, int start, int len, int k) {
int z = , i = ;
for (; z < k; z++) {
if (z >= start && z < start + len) { z += (len - ); continue;}
des.arr[i++] = from.arr[z];
}
for (z = ; z < len; z++) des.arr[i++] = from.arr[start + z];
for (z = k; z < n; z++) {
if (z >= start && z < start + len) { z += (len - ); continue;}
des.arr[i++] = from.arr[z];
}
} bool impossible(Node &cur) {
int cnt = ;
for (int i = ; i < n; i++) if (cur.arr[i - ] + != cur.arr[i]) cnt++;
cnt = cnt ? cnt + : ;
return cnt > * ( - cur.dis);
} int bfs() {
queue<Node> q;
Node start;
for (int i = ; i < n; i++) start.arr[i] = a[i];
start.trans();
try_to_insert(start);
q.push(start);
while (!q.empty()) {
Node cur = q.front(); q.pop();
cur.trans();
if (cur.num == target) return cur.dis;
for (int i = ; i < n; i++)
for (int j = i + ; j <= n; j++)
for (int k = ; k <= n; k++) {
if (k >= i && k <= j) { k = j; continue;}
Node nextn;
create(cur, nextn, i, j - i, k);
nextn.trans();
if (!impossible(nextn) && try_to_insert(nextn)) {
nextn.dis = cur.dis + ;
q.push(nextn);
}
}
}
return ;
} int main() {
int T = ;
while (scanf("%d", &n) == && n) {
printf("Case %d: ", ++T);
target = idx = ;
for (int i = ; i < n; i++) {
scanf("%d", &a[i]);
target *= ;
target += i + ;
}
memset(_head, , sizeof(_head));
int ans = bfs();
printf("%d\n", ans);
}
return ;
}
迭代加深搜索算法总结 + Editing a Book UVa11212题解的更多相关文章
- 埃及分数问题(带乐观估计函数的迭代加深搜索算法-IDA*)
#10022. 「一本通 1.3 练习 1」埃及分数 [题目描述] 在古埃及,人们使用单位分数的和(形如 $\dfrac{1}{a}$ 的,$a$ 是自然数)表示一切有理数.如:$\dfrac{ ...
- 人工智能搜索算法(深度优先、迭代加深、一致代价、A*搜索)
搜索算法问题求解 一.需求分析 分别用深度优先.迭代加深.一致代价.A*搜索算法得到从起始点Arad到目标点Bucharest的一条路径,即为罗马尼亚问题的一个解,在求解的过程中记录每种算法得到的解, ...
- 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 ...
- 7-10Editing aBook uva11212(迭代加深搜索 IDA*)
题意: 给出n( 2<=n<=9) 个乱序的数组 要求拍成升序 每次 剪切一段加上粘贴一段算一次 拍成1 2 3 4 ...n即可 求排序次数 典型的状态空间搜索问题 ...
- uva 11212 - Editing a Book(迭代加深搜索 IDA*) 迭代加深搜索
迭代加深搜索 自己看的时候第一遍更本就看不懂..是非常水,但智商捉急也是没有办法的事情. 好在有几个同学已经是做过了这道题而且对迭代加深搜索的思路有了一定的了解,所以在某些不理解的地方询问了一下他们的 ...
- 算法复习——迭代加深搜索(骑士精神bzoj1085)
题目: Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相 ...
- POJ1129Channel Allocation[迭代加深搜索 四色定理]
Channel Allocation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14601 Accepted: 74 ...
- BZOJ1085: [SCOI2005]骑士精神 [迭代加深搜索 IDA*]
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1800 Solved: 984[Submit][Statu ...
- 迭代加深搜索 POJ 1129 Channel Allocation
POJ 1129 Channel Allocation Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 14191 Acc ...
随机推荐
- 【原创】不用封装jar包 直接引入工程使用的方法(类似android的 is Library功能)
1.制作lib工程,这里我简单制作一个测试类 2.eclipse中 java Project工程引入方法 2.1.新建个java工程,在属性配置中选择 "Java Build Path&qu ...
- ReactiveCocoa入门教程——第一部分
ReactiveCocoa iOS 翻译 2015-01-22 02:33:37 11471 6 15 本文翻译自RayWenderlich ReactiveCocoa ...
- 文字排版--删除线(text-decoration:line-through)
如果想在网页上设置删除线怎么办,这个样式在电商网站上常会见到: 上图中的原价上的删除线使用下面代码就可以实现: .oldPrice{text-decoration:line-through;}
- c语言字符数组和指针的经典用法
1.字符数组 许多情况下,对字符串的处理使用字符数组会更加方便,比如: 我觉得不改变字符串的原有顺序,对字符串进行删除等操作时,使用字符数组效果会更好. eg:给定字符串(ASCII码0-255)数组 ...
- SGU 230. Weighings (拓扑排序)
题意: 给出质量为1~n的n个箱子的m对轻重关系,输出一种可能的箱子的质量排列. Solution: 拓扑排序,注意要处理重边. #include <iostream> #include ...
- 【POJ3580】【splay版】SuperMemo
Description Your friend, Jackson is invited to a TV show called SuperMemo in which the participant i ...
- 4 - 执行TestNG
TestNG以如下几种方式被调用 命令行 ant Eclipse IntelliJ's IDEA 这部分对如何使用命令行方式调用TestNG进行阐述. 假设TestNG已经在你的classpath中, ...
- WIN7下运行hadoop程序报:Failed to locate the winutils binary in the hadoop binary path
之前在mac上调试hadoop程序(mac之前配置过hadoop环境)一直都是正常的.因为工作需要,需要在windows上先调试该程序,然后再转到linux下.程序运行的过程中,报Failed to ...
- Idea中运行Testng时,报SAXParseException:parallel为none的问题原因及解决
今天更新了testng的版本为6.9.10, 在idea中运行测试案例时,报错如下: org.testng.TestNGException: org.xml.sax.SAXParseException ...
- 利用正则表达式,给Json字段加引号
{ scheme: [ { query: [ [{ id: 'stdNumber', title: "标准号", compareType: 2 }], [{ id: 'CnName ...