算法设计与分析——第4章 分治法

分治法的设计思想

将一个难以直接解决的大问题,划分成一些规模较小的子问题,以便各个击破,分而治之。更一般地说,将要求解的原问题划分成k个较小规模的子问题,对这k个子问题分别求解。如果子问题的规模仍然不够小,则再将每个子问题划分为k个规模更小的子问题,如此分解下去,直到问题规模足够小,很容易求出其解为止,再将子问题的解合并为一个更大规模的问题的解,自底向上逐步求出原问题的解。

分治法的典型情况

算法设计与分析——第4章 分治法

分治法的求解过程

一般来说,分治法的求解过程由以下三个阶段组成:

   (1划分:既然是分治,当然需要把规模为n的原问题划分为k个规模较小的子问题,并尽量使这k个子问题的规模大致相同。

   (2求解子问题:各子问题的解法与原问题的解法通常是相同的,可以用递归的方法求解各个子问题,有时递归处理也可以用循环来实现。

  (3合并:把各个子问题的解合并起来,合并的代价因情况不同有很大差异,分治算法的有效性很大程度上依赖于合并的实现。

递归的定义

递归(Recursion)就是子程序(或函数)直接调用自己或通过一系列调用语句间接调用自己,是一种描述问题和解决问题的基本方法。

递归有两个基本要素:

边界条件:确定递归到何时终止;

递归模式:大问题是如何分解为小问题的。

快速排序

快速排序的分治策略是:

1划分:选定一个记录作为轴值,以轴值为基准将整个序列划分为两个子序列r1 ri-1ri+1rn,前一个子序列中记录的值均小于或等于轴值,后一个子序列中记录的值均大于或等于轴值;

2求解子问题:分别对划分后的每一个子序列递归处理;

3合并:由于对子序列r1ri-1ri+1rn的排序是就地进行的,所以合并不需要执行任何操作。

最大子段和问题

给定由n个整数组成的序列(a1, a2, …, an),最大子段和问题要求该序列形如       

的最大值(1ijn),当序列中所有整数均为负整数时,其最大子段和为0。例如,序列(-20, 11, -4, 13, -5, -2)

最大子段和为:

算法设计与分析——第4章 分治法

最大子段和问题的分治策略是:

1划分:按照平衡子问题的原则,将序列(a1, a2, …, an)划分成长度相同的两个子序列(a1, …, a      )(a        1, …, an),则会出现以下三种情况:

a1, …, an的最大子段和=a1, …,a      的最大子段和;

a1, …, an的最大子段和=a     1, …, an的最大子段和;

a1, …, an的最大子段和= 算法设计与分析——第4章 分治法            ,且    算法设计与分析——第4章 分治法

2求解子问题:对于划分阶段的情况①和②可递归求解,情况③需要分别计算   算法设计与分析——第4章 分治法      算法设计与分析——第4章 分治法      ,则s1+s2为情况③的最大子段和。  ,

3合并:比较在划分阶段的三种情况下的最大子段和,取三者之中的较大者为原问题的解。

算法设计与分析——第4章 分治法

棋盘覆盖问题

下面讨论棋盘覆盖问题中数据结构的设计。

1)棋盘:可以用一个二维数组board[size][size]表示一个棋盘,其中,size=2k。为了在递归处理的过程中使用同一个棋盘,将数组board设为全局变量;

2)子棋盘:整个棋盘用二维数组board[size][size]表示,其中的子棋盘由棋盘左上角的下标trtc和棋盘大小s表示;

   (3)特殊方格:用board[dr][dc]表示特殊方格,drdc是该特殊方格在二维数组board中的下标;

  4L型骨牌:一个2k×2k的棋盘中有一个特殊方格,所以,用到L型骨牌的个数为(4k-1)/3,将所有L型骨牌从1开始连续编号,用一个全局变量t表示。

循环赛日程安排问题

设有n=2k个选手要进行网球循环赛,要求设计一个满足以下要求的比赛日程表:

1)每个选手必须与其他n-1个选手各赛一次;

2)每个选手一天只能赛一次。

       按此要求,可将比赛日程表设计成一个 n n-1列的二维表,其中,第 i 行第 j 列表示和第 i 个选手在第 j 天比赛的选手。       

按照分治的策略,可将所有参赛的选手分为两部分,n2k个选手的比赛日程表就可以通过为n/22k-1个选手设计的比赛日程表来决定。递归地执行这种分割,直到只剩下2个选手时,比赛日程表的制定就变得很简单:只要让这2个选手进行比赛就可以了。

最近对问题

算法设计与分析——第4章 分治法

凸包问题

快包的思想是:首先找到S1中的顶点pmax,它是距离直线p1pn最远的顶点,则三角形pmaxp1pn的面积最大。S1中所有在直线pmaxp1左侧的点构成集合S1,1S1中所有在直线pmaxpn右侧的点构成集合S1,2,包含在三角形pmaxp1pn之中的点可以不考虑了。递归地继续构造集合S1,1的上包和集合S1,2的上包,然后将求解过程中得到的所有最远距离的点连接起来,就可以得到集合S1的上包。