迭代加深搜索算法:

对于可以用回溯法解决,但是解答树结点数大的恐怖的问题的一种解决办法,有的问题甚至用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题解的更多相关文章

  1. 埃及分数问题(带乐观估计函数的迭代加深搜索算法-IDA*)

    #10022. 「一本通 1.3 练习 1」埃及分数 [题目描述] 在古埃及,人们使用单位分数的和(形如 $\dfrac{1}{a}​$​​ 的,$a$ 是自然数)表示一切有理数.如:$\dfrac{ ...

  2. 人工智能搜索算法(深度优先、迭代加深、一致代价、A*搜索)

    搜索算法问题求解 一.需求分析 分别用深度优先.迭代加深.一致代价.A*搜索算法得到从起始点Arad到目标点Bucharest的一条路径,即为罗马尼亚问题的一个解,在求解的过程中记录每种算法得到的解, ...

  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. 7-10Editing aBook uva11212(迭代加深搜索 IDA*)

    题意:  给出n( 2<=n<=9) 个乱序的数组  要求拍成升序  每次 剪切一段加上粘贴一段算一次  拍成1 2 3 4 ...n即可     求排序次数 典型的状态空间搜索问题   ...

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

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

  6. 算法复习——迭代加深搜索(骑士精神bzoj1085)

    题目: Description 在一个5×5的棋盘上有12个白色的骑士和12个黑色的骑士, 且有一个空位.在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相 ...

  7. POJ1129Channel Allocation[迭代加深搜索 四色定理]

    Channel Allocation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14601   Accepted: 74 ...

  8. BZOJ1085: [SCOI2005]骑士精神 [迭代加深搜索 IDA*]

    1085: [SCOI2005]骑士精神 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1800  Solved: 984[Submit][Statu ...

  9. 迭代加深搜索 POJ 1129 Channel Allocation

    POJ 1129 Channel Allocation Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 14191   Acc ...

随机推荐

  1. Android中Cursor类的概念和用法

    http://blog.sina.com.cn/s/blog_618199e60101fskp.html 使用过 SQLite数据库的童鞋对 Cursor 应该不陌生,加深自己和大家对Android ...

  2. iOS-NSSDate的使用

    取当前时间的秒数 NSTimeInterval time = [[NSDate date] timeIntervalSince1970];long long int date = (long long ...

  3. Alljoyn 概述(1)

    Alljoyn Overview Feb. 2012- AllJoyn 是什么? • 2011年2月9日发布,由 QuiC(高通创新中心)开发维护的开源软 件项目,采用 Apache license ...

  4. 【转】iOS使用NSMutableAttributedString实现富文本

    iOS使用NSMutableAttributedString实现富文本 在iOS开发中,常常会有一段文字显示不同的颜色和字体,或者给某几个文字加删除线或下划线的需求.之前在网上找了一些资料,有的是重绘 ...

  5. 设置css三种方法的优先级

    有的小伙伴问了,如果有一种情况:对于同一个元素我们同时用了三种方法设置css样式,那么哪种方法真正有效呢?在下面代码中就出现了这种情况 1.使用内联式CSS设置“超酷的互联网”文字为粉色. 2.然后使 ...

  6. VS 编程常见错误及解决方法

    1. VS2013 无法打开包括文件:“cv.h"等一些头文件 解决方法: cv.h是build\include文件夹下的头文件,所在文件夹位置是D:\Program Files (x86) ...

  7. Vijos1675 NOI2005 聪聪和可可 记忆化搜索

    简单题,结果因为理解错题意懵逼了好久…… moveTo[x][y]表示聪聪在节点x,可可在节点y时,聪聪下一步应到达哪一个节点 dp[x][y]表示聪聪在节点x,可可在节点y,且轮到可可行动时,所需时 ...

  8. 【C#枚举】根据EnumName获取Value

    public static int GetEnumValue(Type enumType, string enumName) { try { if (!enumType.IsEnum) throw n ...

  9. .Net用js实现aspx页面删除TextBox输入框的前后空格

    去掉TextBox输入框两头的前后空格:onblur="this.value=this.value.replace(/^\s+|\s+$/g,'');" str为要去除空格的字符串 ...

  10. c# winform 设置winform进入窗口后在文本框里的默认焦点

    c# winform 设置winform进入窗口后在文本框里的默认焦点 进入窗口后默认聚焦到某个文本框,两种方法: ①设置tabindex 把该文本框属性里的tabIndex设为0,焦点就默认在这个文 ...