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. 「题解」NOIP模拟测试题解乱写II(36)

    毕竟考得太频繁了于是不可能每次考试都写题解.(我解释个什么劲啊又没有人看) 甚至有的题目都没有改掉.跑过来写题解一方面是总结,另一方面也是放松了. NOIP模拟测试36 T1字符 这题我完全懵逼了.就 ...

  2. @Component 和 @Bean 的区别

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

  3. JavaScript中数组的集合和映射

    集合 集合(set)是在ES6中引入的一种数据结构,用于表示唯一值的集合,所以它不能包含重复值.接 下来这一小节,就让我们具体来看一下这种新的数据结构. Set集合是一种无重复元素的列表,这是这种数据 ...

  4. call和apply的应用

    相同点 都能够改变方法的执行上下文(执行环境),将一个对象的方法交给另一个对象来执行,并且是立即执行 var arrayLike = { 0: 'item1', 1: 'item2', 2: 'ite ...

  5. Vue.js项目部署到服务器

    1.申请服务器 2.配置Xshell 3.在服务器手动建自己的根目录,把根目录的文件名复制给项目里面config下面的index.js 4.项目开始打包 npm run build 5.打包完成之后把 ...

  6. day 46 Javascript学习

    Javascript学习   JavaScript概述 ECMAScript和JavaScript的关系 1996年11月,JavaScript的创造者--Netscape公司,决定将JavaScri ...

  7. 版本控制git之三-多人协作 变基 推送 拉取 删除远程分支

      版本控制git之三-多人协作 wangfeng7399已关注0人评论350人阅读2019-02-20 21:33:08   如果你想获得一份已经存在了的 Git 仓库的拷贝,比如说,你想为某个开源 ...

  8. 《DSP using MATLAB》Problem 8.9

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

  9. 从三层架构到Spring框架

    首先是软件的应用分层架构 标准三层架构: 1:数据访问层:实现了数据的持久化 2:业务逻辑层:对逻辑的实现及处理,实际上不可能在表示层对数据不做任何处理,但是尽可能的将逻辑分为一层 3:表示层:数据的 ...

  10. C++ 赋值函数为什么返回reference to *this?

    赋值操作为什么要返回 reference to *this? 要弄清这个问题之前,先了解函数的返回值类型:返回值类型,返回引用类型 返回值类型:返回的是一个对象的副本. test operator= ...