【AHOI2013复仇】从一道题来看DFS及其优化的一般步骤和数组分层问题【转】
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及其优化的一般步骤和数组分层问题【转】的更多相关文章
- hdu 4109 dfs+剪枝优化
求最久时间即在无环有向图里求最远路径 dfs+剪枝优化 从0节点(自己添加的)出发,0到1~n个节点之间的距离为1.mt[i]表示从0点到第i个节点眼下所得的最长路径 #include<iost ...
- 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 ...
- 【BZOJ4009】[HNOI2015]接水果 DFS序+整体二分+扫描线+树状数组
[BZOJ4009][HNOI2015]接水果 Description 风见幽香非常喜欢玩一个叫做 osu!的游戏,其中她最喜欢玩的模式就是接水果.由于她已经DT FC 了The big black, ...
- POJ3321 - Apple Tree DFS序 + 线段树或树状数组
Apple Tree:http://poj.org/problem?id=3321 题意: 告诉你一棵树,每棵树开始每个点上都有一个苹果,有两种操作,一种是计算以x为根的树上有几个苹果,一种是转换x这 ...
- 洛谷P1441 砝码称重(搜索,dfs+bitset优化)
洛谷P1441 砝码称重 \(n\) 的范围为 \(n \le 20\) ,\(m\) 的范围为 \(m \le 4\) . 暴力遍历每一种砝码去除情况,共有 \(n^m\) 种情况. 对于剩余砝码求 ...
- POJ2308连连看dfs+bfs+优化
DFS+BFS+MAP+剪枝 题意: 就是给你一个10*10的连连看状态,然后问你最后能不能全部消没? 思路: 首先要明确这是一个搜索题目,还有就是关键的一点就是连连看这个游戏是 ...
- 带分数dfs+剪枝优化
#include<iostream>#include<cstdio>#include<cstdlib>#include<ctime>using name ...
- 3D打印切片软件Cura及CuraEngine原理分析
引言 年初开始进入3D打印行业,受命以Cura为基础,研发一款自主的3D打印切片软件. 自主研发要取其长处,补其不足,首先自然是要搞清楚Cura到底做了什么,读Cura的代码是必需的.我一向都觉得比起 ...
- DFS - leetcode [深度优先遍历]
最短路径=>BFS 所有路径=>DFS 126. Word Ladder II BFS+DFS: BFS找出下一个有效的word进队 并记录step 更新两个变量:unordered ...
随机推荐
- MSSQLSERVER跨服务器连接(远程登录)的示例代码
MSSQLSERVER跨服务器链接服务器创建方法如下 复制代码 代码如下: --声明变量 Declare @svrname varchar(255), @dbname varchar(255), @s ...
- 转-Pycharm中运行Python代码的几种方式
转自:Pycharm中运行Python代码的几种方式 在pycharm中的Python代码运行会出现各种奇葩的问题,比如,密码输入时不显示或没有提示,给我们带来一些麻烦,下面介绍几种代码运行的几种方式 ...
- 33 N皇后问题
原题网址:https://www.lintcode.com/zh-cn/old/problem/n-queens/# n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击. 给定一个整 ...
- 使用 Vue.js 和 Chart.js 制作绚丽多彩的图表
本文作者:Jakub Juszczak 编译:胡子大哈 翻译原文:http://huziketang.com/blog/posts/detail?postId=58e5e0e1a58c240ae35b ...
- java基础之Date类
Date类: Date类概述 类 Date 表示特定的瞬间,精确到毫秒. 构造方法 public Date() public Date(long date) 成员方法 public long getT ...
- 新启vue_cli项目+引入Element
[1]安装vue_cli vue init webpack 项目名字 [2]安装Element-UI cnpm install element-ui -S //写入dependencies cnpm ...
- 05-4-style的代替操作
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- ssm项目 maven 项目pon.xml 配置
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/20 ...
- PKU 百练OJ Arbitrage
http://bailian.openjudge.cn/practice/2240/ #include <iostream> #include <string> #includ ...
- Tomcat Add and Remove 项目时提示 Project facet Java version 1.8 is not supported 错误
原因:项目的jdk和tomcat的jdk版本不同 将eclipse-preference-server-runtime environments 点击你要用的tomcat 点击 edit-jre选择和 ...