算法

**********【深度优先搜索,DFS】【栈】**********
算法思想:
从图的某一点x出发,访问任意一个与之相邻且未被访问到的点y,然后访问任意一个与y相邻且未被访问到的点z,…直到所有点都被访问过为止。
算法实现:
[1]构造一个栈存放顶点,访问第一个顶点v1,并将v1压入栈
[2]V1出栈,将与v1相连的所有未被访问的点入栈
[3]重复[2]直到栈空


**********【广度优先搜索算法,BFS】【队列】**********
算法思想:
从图的某一顶点x出发,访问所有与之相邻且未被访问过的顶点y,z,l,m…,再一次访问所有与y,z,l,m…相邻且未被访问过的顶点,直到所有顶点都被访问过为止
算法实现:
[1]构造一个队列存放顶点,访问第一个顶点v1,将v1入队
[2]v1出队,将所有与v1相连且为被访问过的点入队
[3]重复[2]直到队空


**********【单调栈】**********
就是栈内元素单调按照递增(递减)顺序排列的栈。
单调栈分为单调递增栈和单调递减栈,通过使用单调栈我们可以访问到下一个比他大(小)的元素。
也就是说在队列或数组中,我们需要通过比较前后元素的大小关系来解决问题时我们通常使用单调栈。


**********【分而治之】【递归】**********
分而治之是把问题分解成相互独立的子问题,然后组合他们的答案。分三部分:
[1] 分解原问题为多个子问题(原问题的多个小实例)。
[2] 解决子问题,通常用递归方式来解决子问题。
[3] 组合这些子问题的解决方式,得的原问题的解。


**********【动态规划,Dynamic Programming,DP】【迭代】**********
分而治之是将原问题分解成相互独立的子问题,然后组合所有子问题的解,从而得到最终的原问题的解。
而动态规划是将原问题分解成相互依赖的子问题!!!通常用迭代方式来实现并解决子问题。

动态规划常常适用于有重叠子问题和最优子结构性质的问题。
[1]最优子结构
当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质。
[2]重叠子问题
在用递归算法自顶向下解问题时,每次产生的子问题并不总是新问题,有些子问题被反复计算多次。
动态规划算法正是利用了这种子问题的重叠性质,对每一个子问题只解一次,而后将其解保存在一个表格中,在以后尽可能多地利用这些子问题的解。

问题建模
[1]根据问题,找到【最优子结构】。把原问题从大化小的第一步,找到比当前问题要小一号的最好的结果,而一般情况下当前问题可以由最优子结构进行表示。
[2]确定问题的【边界】。根据上述的最优子结构,一步一步从大化小,最终可以得到最小的,可以一眼看出答案的最优子结构,也就是边界。
[3]根据上述两步,并通过分析最优子结构与最终问题之间的关系,得到【状态转移方程】。

问题求解的各个方法
[1]暴力枚举
所有的动态规划问题都可以通过多层嵌套循环遍历所有的可能,将符合条件的个数统计起来。
只是时间复杂度是指数级的,所以不推荐。
[2]递归
递归的时间复杂度是由递归层数和最优子结构的个数决定的。
在爬阶梯问题,最少找零钱问题中,递归的时间复杂度和空间复杂度都比动态规划方法的差。
但是,在国王与金矿的问题中,不同的数据规模,动态规划方法的时间复杂度和空间复杂度不一定比递归的要好。
[3]备忘录算法
在阶梯数N比较多的时候,递归算法的缺点就显露出来了:时间复杂度很高。
如果画出递归图(像二叉树一样),会发现有很多重复的节点。
然而传统的递归算法并不能识别节点是不是重复的,只要不到终止条件,它就会一直递归下去。
为了避免上述情况,使递归算法能够不重复递归,就把已经得到的节点都存起来,下次再遇到的时候,直接用存起来的结果就行了。这就是备忘录算法。
备忘录算法的时间复杂度和空间复杂度都得到了简化。
[4]动态规划算法:
备忘录算法,虽然已经不错了,但是依然还是从原问题,遍历得到所有的最小子问题,空间复杂度是O(N)。
为了再次缩小空间复杂度,我们可以自底向上的构造递归问题,通过分析最优子结构与最终问题之间的关系,我们可以得到【状态转移方程】。
然后从最小的问题不断往上迭代,即使一直迭代到最大的原问题,也是只依赖于前面的几个最优子结构。
这样,空间复杂度就大大简化。也就得到了动归算法算法。

总结
动态规划与分而治之类似,都是把大问题拆分成小问题,通过寻找大问题与小问题的递推关系,解决一个个小问题,最终达到解决原问题的效果。
分治法在“子问题”和“子子问题”上被重复计算了很多次。
动态规划具有记忆性,通过填表把所有已经解决的子问题答案记录下来。
在新问题里,需要用到的子问题可直接从表中提取,避免重复计算从而节约时间。
所以在问题满足最优性原理时,用动态规划解决问题的核心就在于填表,表填写完毕,最优解也将找到。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值