noip算法总结之搜索

				noip算法总结-搜索
搜索主要是给出一些条件,在不同则状态之间进行转移,如果状态量少的话,那就可以直接上DP了,但搜索一般是状态量大,且不太好转移.
搜索的技巧:
1. 一般对于小数据,如什么n<=20之类的是可以打暴搜的,而搜索的剪枝通常有两种:可行性剪枝和最优性剪枝.但有的时候,如果对于自己的这个剪枝没有十足的把握,那就不要加上.

2. 搜索的时候考虑使用位运算,速度可以加快些.对于一些可以转移的状态之间的搜索,我们可以考虑hash或者是状压下来,进行记忆化,那么对于以后再次搜到这个状态我们就可以直接调用了.
搜索的分类:
1.枚举:
这恐怕是最暴力的了,一般就是直接从初始状态搜索到结束状态,不加任何的剪枝和优化,复杂度一般为指数级别.(n<=20)

2.深度优先搜索(DFS)
这就相当于是走迷宫的时候一条路直接走到底,除非发现当前这条路非法或者走到终点,由于深搜是栈式的储存方式,所以对空间的消耗比较少,但要注意的是状态量的总数如果达到w级别的话就要注意有爆栈的危险了.Windows下是3W左右,Linux是10W左右.一般和回溯搭配使用.

3.广度优先搜索(BFS)
这就相当于是走迷宫的时候多路同时一起进行,走到终点就停止,对于求最优解且话费均等的情况较好,一般用队列实现.

(附:2.3比较:
深搜的空间开销小,但对于数据可能走到解答树的某种节点上,这个节点的后继状态很多,但最优解却在另一个子树中.
广搜的空间开销相对于深搜要多很多,但求解的效率貌似要高些,而且不用担心会爆栈,(p.s在对于树的某些操作,注意是否有爆栈的危险,若有的话,最好改成广搜或是手写栈.)

4.迭代加深 
and IDA*
这种算法结合了深搜和广搜的优点,时间的表现也很不错.
搜索仍是深搜,但对于每次的搜索都给它设置一个深度上限,超过当前的深度上限就直接返回.
经典例题:BZOJ1085骑士精神:
在一个5×5的棋盘上有12个白色 的骑士和12个黑色的骑士, 且有一个空位。在任何时候一个骑士都能按照骑士的走法(它可以走到和它横坐标相差为1,纵坐标相差为2或者横坐标相差为2,纵坐标相差为1的格子)移动到 空位上。 给定一个初始的棋盘,怎样才能经过移动变成如下目标棋盘: 为了体现出骑士精神,他们必须以最少的步数完成任务。
迭代加深再加上h(x)即乐观估计函数,对于当前的状态我们可以乐观地估计出当前的状态到目标状态所需的最多层数,如果大于我们所设置的上界,就返回。
基本步骤:
1.设置一个固定的深度maxdepth,通常为1,即初始的状态。
2.DFS进行搜索,限制层数depth,如果找到答案,则结束,如果没有找到答案则继续下一步。
3.如果DFS途中遇到更深的层,则depth++,并重复2;如果没有遇到,说明搜索已经结束,没有答案。
(中间可用乐观估价函数进行剪枝)
经典例题:codevs1288埃及分数:
在古埃及,人们使用单位分数的和(形如1/a, a是自然数)表示一切有理数。 如:2/3=1/2+1/6,但不允许2/3=1/3+1/3,因为加数中有相同的。 对于一个分数a/b,表示方法有很多种,但是哪种最好呢? 首先,加数少的比加数多的好,其次,加数个数相同的,最小的分数越大越 好。 如: 19/45=1/3 + 1/12 + 1/180 19/45=1/3 + 1/15 + 1/45 19/45=1/3 + 1/18 + 1/30, 19/45=1/4 + 1/6 + 1/180 19/45=1/5 + 1/6 + 1/18. 最好的是最后一种,因为1/181/180,1/45,1/30,1/180都大。 给出a,b(0<a<b<1000),编程计算最好的表达方式。
5.双向广搜:
这个我还没怎么用过,大概是正着搜一次,再从终点倒着搜一次,直到两者相遇。
6.meet in the middle
主要思想:
两人分别从A地和B地出发,向对方的出发点走去.
当他们都走了L/2米的时候"在中间相遇"
找到了一条长度为L米的路径
两种模型:
有向图模型
方程模型
经典例题:

  已知一个n元高次方程:

  

  其中:x1, x2, …,xn是未知数,k1,k2,…,kn是系数,p1,p2,…pn是指数。且方程中的所有数均为整数。

  假设未知数1≤ x≤M, i=1,,,n,求这个方程的整数解的个数。

 

搜索的优化:

剪枝(可行性剪枝,最优性剪枝)

改变搜索顺序,增加更多限制条件(如NOI2005智慧珠游戏,CTSC2003复原)

记忆化(对于同一状态的多次搜索,可以记忆化,下次就可以直接调用之前搜索过的结果)(例:HNOI2013比赛)

...

转载于:https://www.cnblogs.com/DYHNoah/p/4934249.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值