算法设计学习笔记

一、算法与问题
算法是解决问题的一系列步骤；

理解问题，设计算法的一般过程：

解决问题的时候可以首先考虑蛮力法，因为蛮力法一般都能解决，只是效率比较低。使用蛮力法解决问题之后可以再考虑使用其他算法思想进行优化。在使用蛮力法的时候如果解决起来比较费力，可以再次思考一下问题，看看能不能找到什么规律，然后，在该规律之上再求解。

蛮力法往往需要从头到尾遍历所有的可能，而且有时候一个问题可能会有好几种遍历策略，有的策略能够得到问题的解，有一些不能导出最终问题的解，所以，使用蛮力法的时候遍历策略的选择往往是很重要的。好的遍历策略甚至能起到跟贪婪，动态规划策略一样的作用，从这个意义上来说贪婪，动态规划，回溯，分支界限也算是一种蛮力法，只不过是聪明的蛮力法。
优化的思路有以下 3 个方向：

1、蛮力法 ---> 贪婪，动态规划 ---> 回溯，分支界限

2、分治，减治，变治

3、时空权衡

二、蛮力法
蛮力法是一种简单直观的解决问题的办法，常常直接基于问题的描述和所涉及的概念。蛮力法所能解决的问题域也是最广的，但是效率往往不高；

使用蛮力法的算法有：

1、冒泡排序，选择排序

2,、顺序匹配

3、穷举法

三、分治法
分治法设计步骤：
1、将问题实例划分为同一问题的较小的实例，最好拥有同样的规模；
2、求解较小的实例；
3、合并较小问题的解；
分治法算法：
1、归并排序，快速排序
2、折半查找
3、二叉树遍历（前序，中序，后序）
4、大整数乘法和矩阵乘法的分治
5、最近对和凸包问题的分治
四、减治法
减治技术应用了问题的解和同样问题较小实例的解之间的关系，减治法主要有一下三种：
1、减去一个常量 每次减去一个规模相同的常量，一般等于 1 或者 2，例如求 a 的 n 次方可以理解为 f (n)=f (n-1)*a
2、减去一个常量因子 每次迭代减去相同的常数因子，例如每次把问题规模变为原来问题的 1/2，还是求 a 的 n 次方，但是可以这样写递归公式；

3、减去的规模是可变的 每次迭代减去的问题规模是可变的，例如求最大公约数 gcd (m,n) = gcd (n,m mod n)，还有基于快速排序查找第 k 大的数；

减治法算法（减常量）
插入排序、深度优先查找、广度优先查找、拓补排序、生成排列组合、生成子集

减常因子算法
假币问题、约舍夫斯问题

减可变规模
基于快速排序查找第 k 大的数、插值查找、二叉查找树的插入和查找
五、变治法
变治主要体现在变换问题实例上，主要有 3 中类型：
1、问题化简：变换为同样问题一个更简单更方便的实例
2、改变表现：同样问题实例的不同表现
3、问题变换：变换为另一个问题的实例

问题化简： 预排序，高斯消去
改变表现：查找树、堆排序
问题变换：
1、最小公倍数：把求最下公倍数转换为求最大公约数
lcm(m,n) = m*n/gcd(m,n)
六、时空权衡
空间换时间，动态规划和散列也是空间换时间的一种体现

1、计数排序
2、字符串匹配 Horspool, Boyer-Moore, KMP
3、散列
4、B 树索引
七、动态规划
动态规划的出现是用来解决交叠子问题的重复求解问题，具体的求解过程一般分以下两步：
1、确定递推关系
2、根据问题性质采取合适的规划策略，自底向上递推或是自顶向下记忆化搜索
记忆化搜索也要维护一张状态表格，但每次要计算新值的时候会先查找表格该值是否计算过，如果已经计算过就直接用，否则递归计算。

动态规划算法：
1、计算二项系数
C(n,k) = C(n-1,k-1)+C(n-2,k)
2、Warshall 算法计算传递闭包
3、Floyd 算法计算完全最短路径
4、最优二叉树构造
5、背包

八、贪婪
所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择，即贪心选择来达到。这是贪心算法可行的第一个基本要素，也是贪心算法与动态规划算法的主要区别。在动态规划算法中，每步所作的选择往往依赖于相关子问题的解。因而只有在解出相关子问题后，才能作出选择。而在贪心算法中，仅在当前状态下作出最好选择，即局部最优选择。然后再去解作出这个选择后产生的相应的子问题。贪心算法所作的贪心选择可以依赖于以往所作过的选择，但决不依赖于将来所作的选择，也不依赖于子问题的解。正是由于这种差别，动态规划算法通常以自底向上的方式解各子问题，而贪心算法则通常以自顶向下的方式进行，以迭代的方式作出相继的贪心选择，每作一次贪心选择就将所求问题简化为一个规模更小的子问题。

贪婪算法：
1、Prim，Kruskal 算法求最小生成树
2、Dijkstra 算法
3、Huffman
九、迭代改进
从某些可行解出发，然后重复应用一些简单的步骤不断改进它:
1、构造可行解；
2、检查当前解是不是最优的，如果不是，替换它；

迭代改进算法：
1、单纯形法与线性规划
2、最大流
3、递归下降
4、稳定婚姻
5、EM
6、二分图匹配
十、回溯法与分治界限法

其实所谓的状态空间树也就是一颗决策树，每一个决策节点也就是一次迭代，通过对决策树不断地减枝，生长，推导出最终结果；
其应用过程如下:
1、确定遍历规律，也就是决策树的生长顺序；
2、通过回溯或分支界限不断地对树进行生长，减枝；

回溯算法应用：
1、n 皇后问题
2、哈密顿回路
3、生成子集
分支界限：
1、背包
2、旅行商