分治策略—分治法
1.基本概念:
分治策略是对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。
2.问题特征:
(1)该问题规模缩小到一定的程度就容易解决;
(2)该问题可分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。
(3)利用该问题分解出的子问题的解可合并为该问题的解;
(4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
第二条特征是应用分治法的前提,此特征反映了递归思想的应用;能否利用分治法关键完全取决于问题是否具有第三条特征;如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑用贪心法或动态规划法。第四条特征涉及到分治法的效率,如果各子问题是不独立的,则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态规划法较好。
3.分治法基本步骤:
分治法在每一层递归上都有三个步骤:分解–》解决-》合并
Eg: (1)将P分解为较小的子问题 P1 ,P2 ,…,Pk
(2) 递归解决Pi
(3) 合并子问题
注:
递归算法基本思想:找出递归子结构(数学表达式)性质(原问题的解包含了子问题的解)、用子问题的解来递归定义原问题的解、找出递归终止条件(迭代,注意边界和次数)。
分治法基本思想:问题分解(分解成k个规模大致相同的子问题)、子问题递归求解、合并各个子问题的解。
4.改进分治算法的途径:
(1)通过代数变换减少子问题的个数
(2)利用预处理减少递归内部的计算量(eg:快速排序中加入随机化算法)
5.典型例题:
(1)二分搜索:
(2)大整数乘法
(3)Strassen矩阵乘法
(4)棋盘覆蓋:(见附录1)
(5)归并排序:全排列问题(见书p13)
(6)快速排序:找第K大(小)的数(见书p43)
(7)线性时间选择:
(8)最接近点对问题
(9)循环赛日程表
(10)汉诺塔:(见书p12)
附录:
(1) 棋盘覆蓋:
题目:在一个(2^k)*(2^k)个方格组成的棋盘上,有一个特殊方格与其他方格不同,称为特殊方格,称这样的棋盘为一个特殊棋盘。我们要求对棋盘的其余部分用L型方块填满(注:L型方块由3个单元格组成。即围棋中比较忌讳的愚形三角,方向随意),且任何两个L型方块不能重叠覆蓋。L型方块的形态如下:
题目的解法使用分治法,即子问题和整体问题具有相同的形式。我们对棋盘做一个分割,切割一次后的棋盘如图1所示,我们可以看到棋盘被切成4个一样大小的子棋盘,特殊方块必定位于四个子棋盘中的一个。假设如图1所示,特殊方格位于右上角,我们把一个L型方块(灰色填充)放到图中位置。这样对于每个子棋盘又各有一个“特殊方块”,我们对每个子棋盘继续这样分割,直到子棋盘的大小为1为止。
用到的L型方块需要(4^k-1)/3个,算法的时间是O(4^k),是渐进最优解法。
(2) 整数划分问题:
将一个正整数n表示成一系列正整数之和,n=n[1]+n[2]+…+n[k],其中n[1]>=n[2]>=…>=n[k]>=1,k>=1。正整数n的一个这种表示称为n的一个划分。求n的不同划分个数。
用递归算法求解:
(1)递归子结构性质:显然n的一个划分中包含了某个子问题t(<n)的一个划分。这里问题的解是划分数,关键是要研究用子问题的划分数来定义原问题的划分数。在n的所有不同划分中,将其中最大加数n[1]不大于m的划分数个记作q(n,m),则q(n,n)为原问题的解。递归定义如下:
1)当n<1或m<1时,显然q(n,m)=0;
2)当m=1时,n只有一种划分形式,n=1+1+…+1,共n个1相加。q(n,1)=1;
3)当n=1时,显然也只有一种划分形式,q(1,m)=1;
4)当n<m时,因为n[1]不能大于n,故q(n,m)=q(n,n);
5)当n=m时,q(n,n)为n的所有划分个数,它由n[1]<=n-1的划分和n[1]=n的划分(只有一个)组成,q(n,n)=q(n,n-1)+1;
6)当n>m>1时,n[1]不大于m的划分,由n[1]<=m-1的划分和n[1]=m的划分组成,q(n,m)=q(n,m-1)+q(n-m,m)。
(3)http://www.dataguru.cn/thread-480261-1-1.html(详细图文对应的解释,关于归并排序;快速排序;较大子数组;矩阵乘法;寻找逆序对;平面上的分治)