迭代加深搜索

自己看的时候第一遍更本就看不懂。。是非常水,但智商捉急也是没有办法的事情。

好在有几个同学已经是做过了这道题而且对迭代加深搜索的思路有了一定的了解,所以在某些不理解的地方询问了一下他们的见解,

真的是非常有帮助。或许自己想要想非常久才干想明确,还会非常痛苦,略微问一下别人的想法,点上一个方向。剩下的自己就能想得明确了。

迭代加深。

把answer(须要的步数或其它)在主函数里面从零往上递加。此之谓 “层数”,亦可谓之“深度”。用书上的话就是:

从小到大枚举深度上限maxd。每次仅仅考虑深度不超过maxd的节点。

对于能够使用回溯法求解,可是解答树的深度没有明显上限的题目,能够考虑使用迭代加深搜索。

设深度上的上限为maxd(或是设成lim)。当前结点n的深度为dep,须要一个乐观估价函数,此函数的作用推断有没有继续dfs下去的必要:

假设在理想乐观状况下,此结点往下dfs都不能达到终于目标要求。则果断须要剪枝。

(妈蛋就是干啊,写到这个地方发现自己的思路有点不清晰,可能有漏洞就回头去研究了一下代码,然后就哭了……自己原来根本没有理解透彻,须要来理清晰~所以又用掉了好长的时间来搞明确某一步是用来干神马的,真是非常二。。。

对于以下这个代码来讲,我迷乱的地方在于每次都是又一次递归还是就继续了原来的状态递归。。我一直以为是延续了原来的状态(当然之前还有其它的理解误区……太水了我当时跟本就全然没弄明确啊),可是我发现我想不通,然后一阵狂想,最后还是想不通。。然后就郁闷的从D区回到了宿舍。

。然后洗漱之后開始和某小朋友沟通交流了一些事情,某小朋友还是太懂事了搞得自己不开心了,真是笨。。

咳咳扯偏了,,

然后我在某小朋友赶我去睡觉之后,偷偷找来代码看了一眼,然后加了例如以下一组输出推断自己认知上是否有错误,然后特么果然是有错误。。。

人家本就是每次又一次遍历,根本没有延续状态。。那个类里面的内容我将其误当做全局变量真是要死啊。。

好吧那几行全是一样的输出。。

然后一切问题就算是解决完了,把代码就给出例如以下。。

卧槽还是非常蛋疼这个理解误区,这尼玛太水了吧。。菜鸟果然是菜鸟哦,不知道啥时候能进化。

。。。。

#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
class Board
{
public:
int a[16];
int h;
int n;
bool readIn()
{
int i;
scanf("%d",&n);
if (n == 0)
return false;
for (i=0; i<n; i++)
{
scanf("%d",a+i);
}
return true;
}
void printOut()
{
int i;
for (i=0; i<n; i++)
{
printf("%d ", a[i]);
}
printf("\n");
printf("h=%d\n",h);
}
void move(int s,int e,int p)
{
int t[16],i,j;
if (p < s)
{
for (i=0; i<p; i++)
{
t[i]=a[i];
}
for (j=s; j<=e; j++,i++)
{
t[i]=a[j];
}
for (j=p; j<s; j++,i++)
{
t[i]=a[j];
}
for (j=e+1; j<n; j++,i++)
{
t[i]=a[j];
}
}
else
{
for (i=0; i<s; i++)
{
t[i]=a[i];
}
for (j=e+1; j<p; j++,i++)
{
t[i]=a[j];
}
for (j=s; j<=e; j++,i++)
{
t[i]=a[j];
}
for (j=p; j<n; j++,i++)
{
t[i]=a[j];
}
}
memcpy(a,t,sizeof(t));
}
int getH()
{
int cnt,i;
cnt=0;
for (i=0; i<n-1; i++)
{
if (a[i+1] != a[i]+1)
cnt++;
}
if (a[i] != n)
cnt++;
h=cnt;
return cnt;
}
};
int lim;
int f(int dep,int h)
{
return dep*3+h;
}
bool IDDFS(int dep,Board b)
{
int i,j,k;
Board tb;
b.getH(); if (f(dep,b.h) > lim*3)
return false;
if (b.getH() == 0)
return true;
for (i=0; i<b.n; i++)
{
for (j=i; j<b.n; j++)
{
for (k=0; k<i; k++)
{
tb=b;
tb.move(i,j,k);
if (IDDFS(dep+1,tb) == true)
return true;
}
for (k=j+2; k<b.n; k++)
{
tb=b;
tb.move(i,j,k);
if (IDDFS(dep+1,tb) == true)
return true;
}
}
}
return false;
}
int main()
{
Board b;
int prob;
prob=1;
while (b.readIn() == true)
{
for (lim=0; ; lim++)
{
for(int i=0;i<b.n;i++)
printf("%d ",b.a[i]);
printf("\n");
if (IDDFS(0,b) == true)
break;
}
printf("Case %d: %d\n",prob,lim);
prob++;
}
}

用类写的结构体,说真的我还没用过。。

看完某些题目和某些大神打完WF的感言之后如今都认为自己写的这叫什么玩意吧==真是没什么难度了,也没啥不好学的。

这叫算法么,会这些应该是理所应当的事情吧,不练ACM预计也能会。

。就是操蛋,以后好好干,早点变大神不要再当大水笔了。

uva 11212 - Editing a Book(迭代加深搜索 IDA*) 迭代加深搜索的更多相关文章

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

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

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

  3. UVA - 11212 Editing a Book(IDA*算法+状态空间搜索)

    题意:通过剪切粘贴操作,将n个自然段组成的文章,排列成1,2,……,n.剪贴板只有一个,问需要完成多少次剪切粘贴操作可以使文章自然段有序排列. 分析: 1.IDA*搜索:maxn是dfs的层数上限,若 ...

  4. UVA - 11212 Editing a Book (IDA*搜索)

    题目: 给出n(1<n<10)个数字组成的序列,每次操作可以选取一段连续的区间将这个区间之中的数字放到其他任意位置.问最少经过多少次操作可将序列变为1,2,3……n. 思路: 利用IDA* ...

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

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

  6. UVA 11212 Editing a Book

    题意: 有一篇由n个自然段组成的文章.希望将他们排成递增序列.只能剪贴和粘贴交替进行,剪贴时可以剪贴一段连续的自然段. 分析: 用IDA*算法求解.当3*d+h>maxd时剪枝. 代码: #in ...

  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. 埃及分数 迭代加深搜索 IDA*

    迭代加深搜索 IDA* 首先枚举当前选择的分数个数上限maxd,进行迭代加深 之后进行估价,假设当前分数之和为a,目标分数为b,当前考虑分数为1/c,那么如果1/c×(maxd - d)< a ...

  9. 小结:A* & IDA* & 迭代深搜

    概要: 在dfs中,如果答案的深度很小但是却很宽,而且bfs还不一定好做的情况下,我们就综合bfs的优点,结合dfs的思想,进行有限制的dfs.在这里A*.IDA*和迭代深搜都是对dfs的优化,因此放 ...

随机推荐

  1. SQL数据库,增加查询修改以及防sql写入攻击

    SQL添加信息 SQL查询信息 SQL修改信息 SQL语句写入攻击: 普通语句添加信息 sql写入语句攻击: 解决方法:分开传送语句与参数关键:@

  2. PostgreSQL 备忘

    truncate table page_frame_mst; select setval('page_frame_mst_id_seq', 1, false): select setval('imag ...

  3. 【译】x86程序员手册30-8.2 I/O指令

    8.2 I/O Instructions I/O指令 The I/O instructions of the 80386 provide access to the processor's I/O p ...

  4. chr()返回值是当前整数对应的 ASCII 字符。

    #chr() 用一个范围在 range(256)内的(就是0-255)整数作参数,返回一个对应的字符.#返回值是当前整数对应的 ASCII 字符.1 import random input_m =10 ...

  5. RabbitMQ系列(二)--基础组件

    声明:对于RabbitMQ的学习基于某课网相关视频和<RabbitMQ实战指南>一书,后续关于RabbitMQ的博客都是基于二者 一.什么是RabbitMQ RabbitMQ是开源代理和队 ...

  6. Git 分支使用

    一个主分支肯定是不够用的,不同的开发最好放在不同的分支上,在最后进行合并,不然在开发中会相互干扰. PS:环境Window xp,Git-1.8.4-preview20130916(http://gi ...

  7. 服务器的部署与Web项目的发布

    今天给老师的服务器部署项目,这次是第二次,基于第一次的经验,这次可以说是驾轻就熟. 服务器的系统是Windows Server 2008 R2 (64位) 需要安装的软件是:jdk7.TomCat7. ...

  8. NOIP 2018 真・退役记

    目录 NOIp 2018 真・退役记 7.01 7.05 \(summary\) 7.12 7.18 7.26 - 7.27 8.2 8.3 8.3 8.7 8.9 8.20 8.24 8.27 8. ...

  9. STL二分查找函数的应用

    应用二分查找的条件必须是数组有序! 其中二分查找函数有三个binary_serch,upper_bound,lower_bound 测试数组 int n1[]={1,2,2,3,3,4,5}; int ...

  10. python_ 学习笔记(基础语法)

    python的注释 使用(#)对单行注释 使用('''或者""")多行注释,下面的代码肯定了python的牛逼 print("python是世界上最好的语言吗? ...