算法基本思想:大致可分为如下几类:分治算法、贪心算法、动态规划、回溯法、分支限界、概率算法和随机算法等等
分治算法
分治即分而治之。一个问题规模过大不容易直接解决,就可以划分成许多小问题,如果小问题不容易求解,那么可以再划分成规模更小的问题,直到规模小到很容易解决为止,解决这些小问题,再将小问题的解合并成大问题的解。
分治算法常用的实现方法是递归
递归
递归,就是在函数内部调用本函数自身。形式如下
void foo()
{
//
…
foo
();
//
递归
//
…
}
例子:
阶乘
Fibonacci数列
汉诺塔问题
全排列问题
经典问题
(1)二分搜索
(2)大整数乘法
(3)Strassen矩阵乘法
(4)棋盘覆盖
(5)合并排序
(6)快速排序
(7)线性时间选择
(8)最接近点对问题
(9)循环赛日程表
二分搜索
问题:
从一个已经排好序的序列中,查找某一个元素。
1. 将数组从中间分成上下两半,如果中间的值刚好是要查找的元素,直接输出结果。
2. 如果中间的值比要查找的大,那么说明要查找的元素只可能出现在上半段,再对上半段进行二分搜索。
3. 如果中间的值比要查找的小,那么说明要查找的元素只可能出现在下半段,再对下半段进行二分搜索。
棋盘覆盖
问题: 在一个2k×2k 个方格组成的棋盘中,恰有一个方格与其它方格不同,称该方格为一特殊方格,且称该棋盘为一特殊棋盘。在棋盘覆盖问题中,要用图示的4种不同形态的L型骨牌覆盖给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重叠覆盖。
分析: 当k>0时,将2k×2k棋盘分割为4个2k-1×2k-1子棋盘(a)所示。
特殊方格必位于4个较小子棋盘之一中,其余3个子棋盘中无特殊方格。为了将这3个无特殊方格的子棋盘转化为特殊棋盘,可以用一个L型骨牌覆盖这3个较小棋盘的会合处,如 (b)所示,可以把黄色的方格看做是较小棋盘的特殊方格,从而将原问题转化为4个较小规模的棋盘覆盖问题。
递归地使用这种分割,直至棋盘简化为棋盘1×1。