NTU 课程笔记:MAS714(9) 动态规划

1  动态规划和分治的区别

        分治:问题分成几个独立的子问题,他们会分别解决。最后再将各个子问题的结果合并成一个大的结果

        动态规划:问题分成几个相互依赖或者重叠的问题。使用空间换时间的方法避免重复计算,一般从下往上计算子问题。

1.1 动态规划使用条件:优化原则

一个最优决策序列的任何子序列本身一定是相对于 子序列的初始和结束状态的最优的决策序列

2 动态规划举例:斐波那契数列

2.1 斐波那契额数列的描述

其中F(0)=0,F(1)=1

2.2 斐波那契数列的通项

高中还会求的,好像是解一元二次方程然后算系数(记不清了,之后回家翻一下笔记补上去。。。)

总之,斐波那契数列的通项是:

其中是黄金比例

与此同时,我们有:

2.3 通过定义迭代计算

2.3.1 时间复杂度分析 

 

最终我们能得到:

 时间复杂度是指数级的,这么高的原因是:重复计算 

我们计算F(n)的时候,像F(n-2)这种就计算了两边,越往下,重复的越多

2.4 动态规划思路

吸取上面的教训,如果我们将记录 保存下来呢?

这个的时间复杂度是O(n) 【每个Fib(k)都需要算一次,用一次加法两次索引即可】

2.4.1 此时是多项式复杂度吗?

看起来是,实际上不是。

我们这样想:

        这里的输入是一个数字n,用二进制表示,是需要用log_2n位来表示;用十进制表示,也是logn位了。

        但是我们所需要的时间复杂度是O(n),相对于输入的O(logn)数量级来说,是O(2^n)数量级了。

        所以可以说,此时的时间复杂度是O(2^n)

3 最长公共子序列

 3.1 暴力枚举法

 一个一个子序列比较

此时的时间复杂度是(这里2的指数是m或者n都可以【取小的那个】,就是指数数量级)

         我们有个不同的子序列(每个元素可以取可以不取,两个可能性)

        对于每个子序列,我们需要做O(n+m)的比对工作

解释一下O(n+m),假如n<m。

        我们任取一个子序列X(X的长度小于等于n)

        首先比对X与长度位m中的序列的元素,假如长度位m的序列一共遍历到下长方形标蓝的位置,找到X中的元素。

        那么下一个元素(黄),直接从标蓝的后一位开始,不用倒退回找。

        所以最差的情况,是长度为n和长度为m的序列都遍历完了。

        所以时间复杂度是O(n+m)        

 

 3.2 动态规划

3.1 探索性思路

 

注:从前往后一路下去也是可以的

 3.2 动态规划算法

 

 

3.3 求LCS

 

 

 4 带负边最短路径问题

 如果边权重有负数,那么此时之前的迪杰斯特拉算法还生效吗?

答案是:不生效

        考虑上图,如果我们用迪杰斯特拉算法的话,一开始是先从左边的0到1,再从1到中间的0 ,最后从中间的0到3.

        但是实际上最短路径是左0->5->中0->3

 4.1 负环

负循环是一个有向循环,其边长之和为负。

有负循环的图肯定没有最短路径(我们绕着负循环一圈一圈绕,路径的长度就会不断地降下来)

4.1.1 负环的几个定理

1)如果从s到t的路径中有负环,那么不存在一条从s到t的最短路径

2)如果G没有负环,那么一定存在一条从s到t的最短路径

4.2 解决方法:动态规划

令d(v,k)表示从s到v的、最多有k条边的最短路径

于是我们最终要求的结果是:【最多n-1条边,就是每个节点最多遍历一次】

那么d(v,k)怎么计算呢?

  • 如果最短路径的边数量≤k-1,那么d(v,k)=d(v,k-1)
  • 如果最短路径有k条边,我们令(u,v)是最后的一条边,那我们就是寻找s到u的最短路径,其中最多有k-1条边

起始数据信息:

起始点d(s,0)=0

其他的点v:d(v,0)=∞

 4.3 Bellman-Ford 算法

4.3.1 时间复杂度分析 

4.3.2 空间复杂度分析 

记录每条边的长度:O(m)

所有的d(u,k):O(n^2)

所以空间复杂度是O(m+n^2)

4.3.3 空间复杂度改良算法

每一个k的d(u,k)只会使用一次,就是d(u,k+1)的时候,因此,不用每层都保存下来

 时间复杂度不变

空间复杂度降至O(m+n)

4.4 寻找负循环

 证明:

 4.5 寻找负循环

4.6 all-pair shortest path

  

 

5 矩阵相乘

5.1 题目描述

 5.2.解题思路

5.2.1 暴力枚举

 5.2.2 动态规划

 

 5.2.3 递归实现动态规划

 

 

 

 5.2.4 迭代实现

即使用memory记录

 换言之,i从0~n,j从i+1~n,k从i~j,三个都需要循环,所以时间复杂度是O(n3)

 5.2.5 两种算法的比较

递归算法:复杂性高
非递归算法:复杂性较低
原因
递归动态规划算法的子问题被多次重复计算
子问题计算次数呈指数增长
非递归动态规划算法每个子问题只计算一次
子问题的计算随问题规模成多项式增长

 6 动态规划算法设计步骤

将问题表示成多步判断,确定子问题的边界
          整个判断序列就是对应问题的最优解
          每步判断对应一个子问题,子问题类型与原问题一样
确定优化函数,以函数的极大 ( 或极小 ) 作为判断的依据
确定是否满足优化原则 ----- 动态规划算法的必要条件
确定子问题的重叠性
列出关于优化函数的递推方程 ( 或不等式 ) 和边界条件
自底向上计算子问题的优化函数值
备忘录方法 ( 表格 ) 存储中间结果
设立标记函数 s [ i , j ] 求解问题的解
动态规划算法的时间复杂度是对所有子问题( 备忘录 ) 的计 算工作量求和 ( 可能需要追踪解的工作量 )
动态规划算法一般使用较多的存储空间,这往往成为限 制动态规划算法使用的瓶颈因素 .

7举例 :MaxSum

7.1 题目描述

 7.2 方法1:枚举

 7.3 方法2:分治

 
7.4 方法3:动态规划

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UQI-LIUWJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值