分治法
分治算法采取了各个击破的方法,将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。我们只要求出子问题的解,就可得到原问题的解。
在编程过程中,我们经常遇到处理数据相当多、求解过程比较复杂、直接求解法会比较耗时的问题。在求解这类问题时,我们可以采用“各个击破”的方法。具体做法是先把这个问题分解成几个较小的子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个大问题的解法。如果这些子问题还是比较大,还可以继续再把它们分成几个更小的小子问题,依此类推,直至可以直接求出解为止。这就是分治策略的基本思想。
使用分治算法解题的一般步骤如下所示:
(1)分解,将要解决的问题划分成若干个规模较小的同类问题。
(2)求解,当子问题划分得足够小时,用较简单的方法解决。
(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。
分治法所能解决的问题一般具有以下4个特征。
(1)当问题的规模缩小到一定的程度就可以容易地解决问题。此特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加的。
(2)问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质。此特征是应用分治法的前提。它也是大多数问题可以满足的,此特征反映了递归思想的应用。
(3)利用该问题分解出的子问题的解可以合并为该问题的解;此特征最为关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条特征,而不具备第三条特征,则可以考虑用贪婪法(贪心法)或动态迭代法。
(4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。此特征涉及分治法的效率问题。如果各子问题是不独立的,则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然可用分治法,但一般用动态迭代法更好。
PS:值得注意的是,分治是解编程题常用的一种思想,而大多数分治思想都是用递归法来实现的。
分治算法机理
分治策略的思想起源于对问题解的特性所做出的这样的观察和判断:原问题可以被划分成k个子问题,然后用一种方法将这些子问题的解合并,合并的结果就是原问题的解。既然我们知道可以以某种方式构造出来,就没有必要(使用枚举回溯)进行大批量的搜索了。
枚举、回溯、分治算法利用了计算机工作的第一个特点:高