奇偶剪枝学习笔记

描述

编辑

现假设起点为(sx,sy),终点为(ex,ey),给定t步恰好走到终点,
s
       
|
       
|
       
|
       
+
e
如图所示(“|”竖走,“—”横走,“+”转弯),易证abs(ex-sx)+abs(ey-sy)为此问题类中任意情况下,起点到终点的最短步数,记做step,此处step1=8;
s
 
 
+
 
|
+
     
|
       
+
e
如图,为一般情况下非最短路径的任意走法举例,step2=14;
step2-step1=6,偏移路径为6,偶数(易证);

结论

编辑

推广之,若 t-[abs(ex-sx)+abs(ey-sy)] 结果为非偶数(奇数),则无法在t步恰好到达;
返回,false;
反之亦反。

原理补充

编辑

鉴于很多同学对奇偶剪枝根本原理的兴趣,所以hj决定再补充一下本词条。
还是以这个为例子吧,现在我把矩阵填满 0 和 1 [1] 
0
1
0
1
0
1
0
1
0
1
0
1
0 1 0
1
0 1 0 1
0
1
0
1
0
我们现假设从 0 开始走,则不难证明,
从任意 0 走到任意 1 始终是奇数步;
从任意 0 走到任意 0 始终是偶数步;
引用描述里的“例子”, s 到 e 的最短步数为 t (当然你也可以理解成此时到终点刚好剩余 t 步等等)。
则,我们从 s 到 e 的步数之和(或者说总距离)总可以表示成 sum= t + extra ( extra>=0 ),其中 extra 表示额外的步数。[2] 
比如“例子”里面的,做例1吧
s
 
 
+
 
|
+
     
|
       
+
e
此时 t=8,sum=14,所以我们容易得到 extra=6。也就是说按照这个走法,需要在最短的步数上再走额外的 6 步(先不用太在意这些偏移是在什么地方产生的)。
在来一个例2吧,
s
 
 
+
 
|
+
     
|
  + e
+
   
此时,t=7,sum=15,所以我们也容易得到 extra=8。
根据理科生的天性,由这两个一般性的例子,我们很容易嗅察到 extra 都为偶数。先带着疑惑,
再来看我给的 0 、1 矩阵。
0
1
0
1
0
1
0
1
0
1
0
1
0 1 0
1
0 1 0 1
0
1
0
1
0
设左上角坐标为(1,1),右下角坐标为(5,5).
那么我们给的例1,
起点 s 的坐标为(1,1),此点为“0”;
终点 e 为(5,5),此点为“0”。
所以t=8,为偶数。
现在我们再倒过来看,从终点(也就是 e )出发,把最短步数 t=8 耗费掉,不妨这样走,
s
      +
     
+
      |  
    +  
   
e
如图所示从 e (5,5)耗费 8 步走到了(1,5)点。
因为是从 0 走偶数步,所以走到的坐标也一定是 0 ,就像这里的(1,5)点是 0 一样。
这是一个递归的过程,首先如果从0开始,目的地也是0,那末其中的最短距离t必然是个偶数,可其中有可能有障碍物或需要绕弯的情况,那末我们就现将最短距离t用于绕弯,从开始的0,走t步不管怎么走都只能到0,而这个0到终点0的最短路径t也必然是偶数,一直递归下去,直到你绕够了到达终点,这中间你额外的步数都是偶数。
注意到,(1,5)点和起点 s (1,1)都是 0,也就是说,这个 extra 必然是偶数!
再看例2,同样从终点 e 开始耗费 t=7 步,
则所到的点一定是 0 (不管她在哪里),再从这个点回到起点 s ,所用的 extra 也必然是个偶数!
所以无论如何,sum= t + extra ( extra>=0 ) 中的 extra 都是一个偶数
那么我们就可以用公式 t-[abs(ex-sx)+abs(ey-sy)] 计算出extra是否为偶数来判断当前点能否恰好在这么多步到达终点了。
有的同学可能会说以 1 为 起点呢。。其实是一样的啦,自己去捣鼓吧。
核心代码:
ans=t-time-abs(dx-x)-abs(dy-y);
if(ans<||ans&) return;

说了这么多,再总结一下吧!

什么是奇偶剪枝?

把矩阵看成如下形式:

0 1 0 1 0 1

1 0 1 0 1 0

0 1 0 1 0 1

1 0 1 0 1 0

0 1 0 1 0 1

从为 0 的格子走一步,必然走向为 1 的格子 。

从为 1 的格子走一步,必然走向为 0 的格子 。

即:

从 0 走向 1 必然是奇数步,从 0 走向 0 必然是偶数步。

所以当遇到从 0 走向 0 但是要求时间是奇数的或者 从 1 走向 0 但是要求时间是偶数的,都可以直接判断不可达!

比如有一地图:

S...
....
....
....
...D

要求从S点到达D点,此时,从S到D的最短距离为s = abs ( dx - sx ) + abs ( dy - sy )。

如果地图中出现了不能经过的障碍物:

S..X
XX.X
...X
.XXX
...D

此时的最短距离s' = s + 4,为了绕开障碍,不管偏移几个点,偏移的距离都是最短距离s加上一个偶数距离。

就如同上面说的矩阵,要求你从0走到0,无论你怎么绕,永远都是最短距离(偶数步)加上某个偶数步;要求你从1走到0,永远只能是最短距离(奇数步)加上某个偶数步。

这里我来讲一下搜索中要用到的奇偶剪枝的原理:

看张图,没障碍物#时,S到E的最短路长为6,但是当有障碍物时,就要绕行了

看这张图,黑色为最短路径,当他绕行(红色加蓝色部分)时,其中蓝色部分其实还是最短路径部分平移来的,所以多走的步数也就是红色部分

对于红色部分我们可以分为两部分,一部分是远离最短路径的步数,另一部分是回到最短路径的部分,他们一定是对称的,所以多走的步数一定是偶数!!!

所以要是问走x步能否到达e,就算出最短路径长y,如果x-y是偶数就能到达,否则不能到达!

DFS中的奇偶剪枝学习笔记的更多相关文章

  1. DFS中的奇偶剪枝(技巧)

    剪枝是什么,简单的说就是把不可行的一些情况剪掉,例如走迷宫时运用回溯法,遇到死胡同时回溯,造成程序运行时间长.剪枝的概念,其实就跟走迷宫避开死胡同差不多.若我们把搜索的过程看成是对一棵树的遍历,那么剪 ...

  2. HDU 1010 Tempter of the Bone【DFS经典题+奇偶剪枝详解】

    Tempter of the Bone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Othe ...

  3. JavaSE中Collection集合框架学习笔记(2)——拒绝重复内容的Set和支持队列操作的Queue

    前言:俗话说“金三银四铜五”,不知道我要在这段时间找工作会不会很艰难.不管了,工作三年之后就当给自己放个暑假. 面试当中Collection(集合)是基础重点.我在网上看了几篇讲Collection的 ...

  4. JavaSE中Collection集合框架学习笔记(3)——遍历对象的Iterator和收集对象后的排序

    前言:暑期应该开始了,因为小区对面的小学这两天早上都没有像以往那样一到七八点钟就人声喧闹.车水马龙. 前两篇文章介绍了Collection框架的主要接口和常用类,例如List.Set.Queue,和A ...

  5. 浏览器中js执行机制学习笔记

    浏览器中js执行机制学习笔记 RiverSouthMan关注 0.0772019.05.15 20:56:37字数 872阅读 291 同步任务 当一个脚本第一次执行的时候,js引擎会解析这段代码,并 ...

  6. JavaSE中Collection集合框架学习笔记(1)——具有索引的List

    前言:因为最近要重新找工作,Collection(集合)是面试中出现频率非常高的基础考察点,所以好好恶补了一番. 复习过程中深感之前的学习不系统,而且不能再像刚毕业那样死背面试题,例如:String是 ...

  7. JS和JQuery中的事件托付 学习笔记

    事件托付事实上并非一个非常高级的技巧,比方在一个页面里面.当仅仅存在两个button的时候.可能你给button加入监听是这种:(本文不考虑浏览器兼容性.关于事件的兼容性可參考前面的学习笔记) < ...

  8. <<C++标准程序库>>中的STL简单学习笔记

    0. 内容为个人学习笔记, 仅供参考, 如有错漏, 欢迎指正! 1. STL中的所有组件都是由模板构成的, 所以其元素可以是任意型别的. 组件有: - 容器: 管理某类对象的集合. 不同的容器有各自的 ...

  9. C++中临时对象的学习笔记

    http://www.cppblog.com/besterChen/category/9573.html 所属分类: C/C++/STL/boost  在函数调用的时候,无论是参数为对象还是返回一个对 ...

随机推荐

  1. cell上添加倒计时,以及时差问题的解决

    原址 http://www.cnblogs.com/zhangmaliang/p/5102518.html 最近项目中用到了tableView的多个cell倒计时系统问题,本觉得很简单的一个事,一做发 ...

  2. 命令行执行php脚本 中$argv和$argc

    在实际工作中有可能会碰到需要在nginx命令行执行php脚本的时候,当然你可以去配置一个conf用外网访问. 在nginx命令行中 使用 php index.php 就可以执行这个index.php脚 ...

  3. php中static 静态关键字

    一直依赖对于php中static关键字比较模糊,只是在单例模式中用过几次.上网查了查,没有找到很全的介绍,自己总结一下. 根据使用位置分为两部分 1.函数体中的静态变量 2.类中的静态属性和方法 1 ...

  4. 虚拟机创建流程中neutron代码分析(一)

    前言: 在openstack的学习当中有一说法就是网络占学习时间的百分之七十.这个说法或许有夸大的成分,但不可否认的是openstack中的 网络是及其重要的部分,并且难度也是相当大.试图通过nova ...

  5. 学习 Kubernetes 的 Why 和 How - 每天5分钟玩转 Docker 容器技术(114)

    这是一个系统学习 Kubernetes 的教程,有下面两个特点: 系统讲解当前最流行的容器编排引擎 Kubernetes包括了安装部署.应用管理.网络.存储.监控.日志管理等多各个方面. 重实践并兼顾 ...

  6. Linux第三节

    三期第三讲1.ls --help:查看帮助(man 命令) :ls -l: 长格式形式: ls -i: 文件的inode节点: ls -t: 按修改时间排序: ls -a :显示隐藏文件: 2.文件管 ...

  7. 比较日期大小以及获取select选中的option的value

    原生JavaScript如何获取select选中的value // 1. 拿到select对象 const selectObject = document.getElementById('test') ...

  8. Linux发行版 CentOS6.5下的分区操作

    本文地址http://comexchan.cnblogs.com/ ,尊重知识产权,转载请注明出处,谢谢! 查询磁盘信息并作分区规划 执行下述命令查询磁盘信息: fdisk -l 可知.数据盘大小50 ...

  9. js 停止事件冒泡 阻止浏览器的默认行为(阻止a标签跳转 )

    在前端开发工作中,由于浏览器兼容性等问题,我们会经常用到"停止事件冒泡"和"阻止浏览器默认行为". 1..停止事件冒泡 JavaScript代码 //如果提供了 ...

  10. golang 多维数组

    具体的题目如下:(就是将多维数组的行列互换) A multi-dimensional array is an array of arrays. 2-dimensional arrays are the ...