http://www.cppblog.com/MatoNo1/archive/2012/09/23/191708.html

———————————————————————————————————————————————————

普通DFS(不加迭代)的优化方法主要有:
(1)可行性剪枝,如果遇到已经无法产生可行解的情况就剪枝,有时候,可行性剪枝也可以指在搜索过程中对不合法情况的剔除;
(2)最优性剪枝:如果遇到已经无法产生比目前得到的最优解还要优的解的情况就剪枝,这其中包括启发式最优性剪枝(即分支限界),对目前解的进展情况作乐观估计,如果估计值都不能超越目前的最优解,则剪枝;
(3)通过改变搜索顺序,尽早得出较优解,从而为后面的剪枝提供余地;
(4)通过预处理等手段,提前得到启发值或者较优解,为后面的剪枝提供余地;

一般步骤:
(1)预处理,当然是写在最前面,在搜索前得到启发值等东东;
(2)搜索过程中,先写最优性剪枝(包括已经到达搜索终点了,也应该判断一下,提前排除不是最优解的情况);
(3)再判定搜索终点,如果到了,也不要马上更新解,而是要判定这个解是否符合要求,再更新;
(4)若未到终点,再写可行性剪枝;
(5)最后写搜索过程,包括需要改变搜索顺序的情况。

注意事项:数组的分层问题。
这是一个很严重的问题,因为分层出错很可能会导致一些很怪的错误出现,难以发现。在搜索题的调试技巧这一篇中,已经提到了这个问题,本题又涉及到了。
一般来说,搜索过程中使用的数组(包括变量,可以视为零维数组)可以分为以下三类:
(1)在搜索过程中,只会引用其值,不会修改的数组(比如预处理中得到的那些东东),相当于常量;
(2)在搜索过程中,会改变其值,但在搜索完毕后能改回原值的数组;
(3)在搜索过程中,会改变其值,且在搜索完毕后也改不回原值的数组。
对于(1)(2)类数组,不需分层,但对于第(3)类数组一定要分层。这是因为这些数组在多层搜索中都需要修改,而且搜索完了也改不回来,如果不分层,则当后面的搜索完毕以后,要继续搜索前面的,引用的将是后面的值,就会出错。
对于第(3)类数组,有的已经“自然分层”(每层搜索修改的元素都不一样),比如本题代码中的R[][]、C[][]。然而有的并没有自然分层,比如本题的len、pos[]、tmp[]等,因此对于这些数组,需要再加一维,对于不同层使用该维不同的元素即可。

下面是本题的算法:
使用DFS搜索每个位置的挡板是否需要放。搜索时,先搜竖的再搜横的,由于题目要求每个连通块都必须是矩形,因此对于竖的,如果该位置的上方两个相邻位置的横的没有全放(包括只放了一个),则该位置的竖的放不放取决于其上一行对应位置的竖的有没有放(第一行除外),如果两个横的都放了,则这里的竖的既可以放也可以不放(先搜不放的情况)。当然,一行的两个1之间必须至少有一个竖的,这是可行性限制。在搜横的的时候,按照该行所放的竖的,分成若干段,显然每一段要么下面都用横的封上,要么一个都不封上。其中,如果该段所在的连通块里面有1,且下一行对应位置也有1,则必须封上;若该段所在连通块里面没有1,则不能封上(因为不能有一个连通块里一个1都没有),否则可以自由选择封还是不封(当然也是先搜不封的)。这样一直搜到最后一行的竖的后,还要判断最后一行有没有连通块里没1,若没有,则为一个可行解。启发式优化:设D[i]为第i行及以后至少要几个挡板(若某行有K个1,则至少需要(K-1)个竖的;若某列有K个1,则至少需要(K-1)个横的,累加起来即可,显然这是乐观估计),D[i]可以预处理出来,当做启发值。

【AHOI2013复仇】从一道题来看DFS及其优化的一般步骤和数组分层问题【转】的更多相关文章

  1. hdu 4109 dfs+剪枝优化

    求最久时间即在无环有向图里求最远路径 dfs+剪枝优化 从0节点(自己添加的)出发,0到1~n个节点之间的距离为1.mt[i]表示从0点到第i个节点眼下所得的最长路径 #include<iost ...

  2. hdu 5506 GT and set dfs+bitset优化

    GT and set Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Probl ...

  3. 【BZOJ4009】[HNOI2015]接水果 DFS序+整体二分+扫描线+树状数组

    [BZOJ4009][HNOI2015]接水果 Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, ...

  4. POJ3321 - Apple Tree DFS序 + 线段树或树状数组

    Apple Tree:http://poj.org/problem?id=3321 题意: 告诉你一棵树,每棵树开始每个点上都有一个苹果,有两种操作,一种是计算以x为根的树上有几个苹果,一种是转换x这 ...

  5. 洛谷P1441 砝码称重(搜索,dfs+bitset优化)

    洛谷P1441 砝码称重 \(n\) 的范围为 \(n \le 20\) ,\(m\) 的范围为 \(m \le 4\) . 暴力遍历每一种砝码去除情况,共有 \(n^m\) 种情况. 对于剩余砝码求 ...

  6. POJ2308连连看dfs+bfs+优化

    DFS+BFS+MAP+剪枝 题意:       就是给你一个10*10的连连看状态,然后问你最后能不能全部消没? 思路:      首先要明确这是一个搜索题目,还有就是关键的一点就是连连看这个游戏是 ...

  7. 带分数dfs+剪枝优化

    #include<iostream>#include<cstdio>#include<cstdlib>#include<ctime>using name ...

  8. 3D打印切片软件Cura及CuraEngine原理分析

    引言 年初开始进入3D打印行业,受命以Cura为基础,研发一款自主的3D打印切片软件. 自主研发要取其长处,补其不足,首先自然是要搞清楚Cura到底做了什么,读Cura的代码是必需的.我一向都觉得比起 ...

  9. DFS - leetcode [深度优先遍历]

    最短路径=>BFS    所有路径=>DFS 126. Word Ladder II BFS+DFS: BFS找出下一个有效的word进队 并记录step 更新两个变量:unordered ...

随机推荐

  1. @Component 和 @Bean 的区别

    Spring帮助我们管理Bean分为两个部分,一个是注册Bean,一个装配Bean.完成这两个动作有三种方式,一种是使用自动配置的方式.一种是使用JavaConfig的方式,一种就是使用XML配置的方 ...

  2. jquery 判断当前设备是PC端还是移动端

    $(function(){ var system = { win: false, mac: false, xll: false, ipad:false }; //检测平台 var p = naviga ...

  3. hibernate使用truncate清空表 截断表

    public void truncateTable(Session session, String tableNameInDb) { String sql = " truncate tabl ...

  4. 《DSP using MATLAB》Problem 8.3

    代码: %% ------------------------------------------------------------------------ %% Output Info about ...

  5. selenium 三种断言以及异常类型

    selenium 提供了三种模式的断言:assert .verify.waitfor Assert 失败时,该测试将终止. Verify 失败时,该测试将继续执行,并将错误记入日显示屏 .也就是说允许 ...

  6. 一个WEB网站高并发量的解决方案

    一个小型的网站,可以使用最简单的html静态页面就实现了,配合一些图片达到美化效果,所有的页面均存放在一个目录下,这样的网站对系统架构.性能的要求都很简单.随着互联网业务的不断丰富,网站相关的技术经过 ...

  7. 2018-8-10-VisualStudio-使用三个方法启动最新-C#-功能

    title author date CreateTime categories VisualStudio 使用三个方法启动最新 C# 功能 lindexi 2018-08-10 19:16:52 +0 ...

  8. 模板:exlucas

    求$C_n^m mod p$,其中p不是质数且不保证p能分解为几个不同质数的乘积(也就是不能用crt合并) #include<iostream> #include<cstdio> ...

  9. QInotifyFileSystemWatcherEngine::addPaths: inotify_add_watch failed: 设备上没有空间

    解决办法: 添加最大监控文件数量 临时解决:(重启之后恢复) 命令设置:sudo sysctl fs.inotify.max_user_watches=524288 生效: sudo sysctl - ...

  10. JavaSE_01_Exception类

    1.1 异常概念 指的是程序在执行过程中,出现的非正常的情况,最终会导致JVM的非正常停止. 在Java等面向对象的编程语言中,异常本身是一个类,产生异常就是创建异常对象并抛出了一个异常对象.Java ...