找工作——算法设计
1. 分治法
基本思想:将一个规模为n的问题分解为k个规模较小的子问题,这些字问题互相独立且与原问题相同。递归的解这些子问题,然后将各子问题的阶合并得到原问题的解。
eg:
二分搜索:给定已排序好的额n个元素,现在要在这n个元素中找出一特定元素x
归并排序 快速排序
2. 动态规划
动态规划与分治法类似,其基本思想也是讲待求解问题分解成若干个子问题,先求解子问题,然后从这些子问题的解得到原问题的解。与分治法不同的是适用于动态规划法求解的问题,经分解得到的子问题往往不是相互独立的。若用分治法来解这类问题,则经分解得到的子问题往往不是相互独立的。若用分治法来解这类问题,则分解得到的子问题数目太多,以至于最后解决原问题需要耗费指数时间,然而不同子问题数目常常只有多项式量级。在用分治法求解时,有些子问题被重复计算了许多次。如果我们能够保存已解决的子问题的答案,而在需要时再找出以求得的答案,这样就可以避免大量的重复计算,从而得到多项式时间的算法。为了达到这个目的,我们可以用一个表来记录所有已解决的子问题的答案。不管子问题以后是否被用到,只要它被计算过,就将其结果填入表中。这就是动态规划法的基本思路。具体的动态规划算法多种多样,但它们都具有相同的填表格式。
可以用动态规划算法解决问题所具有的两个重要性质:
最优子结构性质:当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质。在动态规划算法中,问题的最优子结构性质使得我们能够以自底向上的方式递归从子问题的最优解逐步构造出整个问题的最优解。同时,它也使得我们能在相对小的子问题空间中考虑问题。
子问题重叠性:在用递归法自顶向下解此问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。动态规划正是利用了这些子问题的重叠性质,对每一个子问题只解一次,而后将其保存在一个表格中,当再次需要解此问题时,只是简单地用常数时间查看一下结果。通常不同的子问题个数随输入问题的大小呈多项式增长。因此,用动态规划算法只需要多项式时间,从而获得较高的解题效率。
动态规划算法通常用于求解具有某种最优性质的问题。在这类问题中,可能会有许多可行解。每一个解都对应一个值,我们希望找到具有最优值(最大值或最小值)的那个解。设计一个动态规划算法,通常按如下的几个步骤进行:
- 找出最优解的性质,并刻画其结构特征;
- 递归的定义最优值;
- 以自底向上的方式计算出最优值;
- 根据计算最优值得到的信息,构造一个最优解。
前三个步骤是动态规划的基本步骤,在只需要求出最优值的情形,第四步可以省去。若需要求出问题的一个最优解,则必须执行步骤4,在步骤3中计算最优值时,通常需记录更多的信息,以便在步骤4中根据所记录的信息,快速构造一个最优解。
eg:
矩阵连乘问题:给定n个矩阵{A1,A2,.....,An},其中Ai与Ai+1是可乘的,我们要计算出n个矩阵的连乘积。
3. 贪心算法
当一个问题具有最优子结构性质时,我们会想到用动态规划法去求解。但有时会有更简单有效的办法。
可以用贪心算法求解的的问题一般具有两个重要的性质:贪心选择性和最优子结构性质。
贪心选择性:指所求问题的整体最优解可以通过一系列局部最优的选择来达到。这是贪心算法可行的第一个基本要素,也是贪心算法与动态规划算法的主要区别。在动态规划算法中,每步所作的选择往往依赖于相关子问题的解,因而只有在接触相关子问题后,才能做出选择。贪心算法中,仅在当前状态下做出最好选择,即局部最优选择,然后再去解作出这个选择后产生的相应子问题。贪心算法所作的贪心选择可以依赖于以往所做过的选择,但绝不依赖于将来所作的选择,也不依赖于子问题的解。正式由于这种差别,动态规划算法通常以自底向上的方式解各子问题,而贪心算法则通常以自顶向下的方式进行,以迭代的方式作出相继的贪心选择,每做一次贪心选择就将所求问题简化为一个规模更小的子问题。
最优子结构性质:当一个问题的最优解包含着它的子问题的最优解时,称此问题具有最优子结构性质。问题所具有的这个性质是该问题可用动态规划算法和贪心算法求解的一个关键特征。