【经典算法】分治策略

一、什么是分治  

  有很多算法是递归的:为了解决一个给定的问题,算法要一次或多次递归调用其自身来解决的子问题。这些算法通常采用分治策略:将原问题划分为n个规模较小而结构与原问题相似的子问题;递归地解决这些子问题,然后再合并其结果,就得到原问题的解。

  习惯上,在正文中至少含有两个递归调用的例程叫作分治算法,而正文中只含有一个递归调用的例程不是分治算法。

 

二、分治算法的三个步骤

  分治模式中,我们递归地求解一个问题,在每层递归中应用如下三个步骤:

  分解(Divide)步骤将问题划分为一些子问题,子问题的形式与原问题一样,只是规模更小。

  解决(Conquer)步骤递归地求解出子问题。如果子问题规模足够小,则停止递归,直接求解。

  合并(Combine)步骤将子问题的解合并为原问题的解。

  当子问题足够大,需要递归求解时,我们称之为递归情况(recursive case)。当子问题变得足够小,不再需要递归时,我们说递归已经”触底“,进入了基本情况(base case)。有时,除了与原问题形式完全一样的规模更小的子问题外,还需要求解与原问题不完全一样的子问题。我们将这些子问题的求解看做合并步骤的一部分。

  

 

三、分治算法的应用场景

  1、该问题的规模缩小到一定的程度就可以容易的解决;

  2、该问题可以分解为若干规模较小相同的问题,即该问题具有最小最优子结构。

  3、该问题分解出的子问题的解可以合并成为该问题的解。

  4、该问题所分解出的各子问题是相互独立的,即子问题之间不包括公共的子问题。

  

  第一条特征是绝大多数问题都可以满足的,因为问题的计算复杂性一般是随着问题规模的增加而增加;

  第二条特征是应用分治法的前提,它也是绝大多数问题可以满足的,此特征反映了递归思想的应用

  第三条特征是关键,能否利用分治法完全取决于问题是否具有第三条特征,如果具备了第一条和第二条而不具备第三条,则可以

考虑用贪心法或动态规划法。

  第四条特征涉及到分治法的效率,如果各子问题是不独立的则分治法要做许多不必要的工作,重复地解决公共的子问题,此时虽然可用分治法,但一般用动态规划法要好。

 

四、可使用分治法解决的问题

  (1)二分搜索

  (2)大整数乘法

  (3)Strassen矩阵乘法

  (4)棋盘覆盖
  (5)合并排序
  (6)快速排序
  (7)线性时间选择
  (8)最接近点对问题
  (9)循环赛日程表
  (10)汉诺塔
 
  
五、其他比较好的资料
  http://www.cnblogs.com/web-application-security/archive/2012/06/15/divide_and_conquer.html
 
参考资料:
     1.http://blog.csdn.net/com_stu_zhang/article/details/7233761
     2.《王道程序员求职宝典》
     3.《算法导论》
     4.《数据结构与算法分析C++描述》(第三版)

 

posted @ 2015-01-24 20:02  vincently  阅读(1018)  评论(0编辑  收藏  举报