《算法导论》第15章 动态规划 个人笔记
来源:互联网 发布:网贷系统源码下载 编辑:程序博客网 时间:2024/05/18 03:06
第15章 动态规划
15.1 钢条切割
1、递归实现:
CUT-ROD(p,n)if n == 0 return 0q = -\inffor i = 1 to n q = max(q,p[i]+CUT-ROD(p,n-i))return q
分析CUT-ROD的运行时间,令T(n)表示第2个参数值为n时CUT-ROD的调用次数。
2、使用动态规划
- 带备忘的自顶向上法
MEMOIZED-CUT-ROD(p,n)let r[0..n] be a new arrayfor i = 0 to n r[i] = -\infreturn MEMOIZED-CUT-ROD-AUX(p,n,r)MEMOIZED-CUT-ROD-AUX(p,n,r)if r[n] >= 0 return r[n]if n == 0 q = 0else q = -\inf for i = 1 to n q = max(q,p[i]+MEMOIZED-CUT-ROD-AUX(p,n-i,r))r[n] = qreturn q
- 自底向上法
BOTTOM-CUT-ROD(p,n)let r[0..n] be a new arrayr[0] = 0for j = 1 to n q = -\inf for i = 1 to j q = max(q,p[i]+r[j-i]) r[j] = qreturn r[n]
两种方法具有相同的渐进运行时间,但自底向上法没有频繁的递归函数调用的开销,所以较自顶向下法有更小的系数。
3、重构解
EXTENDED-BOTTOM-CUT-ROD(p,n)let r[0..n] and s[0..n] be a new arrayr[0] = 0for j = 1 to n q = -\inf for i = 1 to j if q < p[i]+r[j-i] q = p[i]+r[j-i] s[j] = i r[j] = qreturn r[n]PRINT-CUT-ROD-SOLUTION(p,n)(r,s) = EXTENDED-BOTTOM-CUT-ROD(p,n)while n > 0 print s[n] n = n - s[n]
15.2 矩阵链乘法
m[i,j]表示
MATRIX-CHAIN-ORDER(p)n = p.length - 1let m[1..n,1..n] and s[1..n-1,2..n] be a new arrayfor i = 1 to n m[i,i] = 0for l = 2 to n //l is the chain length for i = 1 to n-l+1 j = i + l -1 m[i,j] = \inf for k = i to j-1 q = m[i,k] + m[k+1,j] + p[i-1]p[k]p[j] if q < m[i,j] m[i,j] = q s[i,j] = kreturn m,sPRINT-OPTIMAL-PARENS(s,i,j)if i == j print "A"else print "(" PRINT-OPTIMAL-PARENS(s,i,s[i,j]) PRINT-OPTIMAL-PARENS(s,s[i,j]+1,j) print ")"
15.3 动态规划原理
最优子结构
在发掘最优子结构性质的过程中,实际上遵循了如下的通用模式:
1. 证明问题最优解的第一个组成部分是做出一个选择
2. 对于一个给定问题,在其可能的第一步选择中,假定已经知道哪种选择才会得到最优解
3. 给定可获得最优解的选择后,确定这次选择会产生哪些子问题,以及如何最好地刻画子问题空间
4. 利用“剪切-粘贴”技术证明作为构成原问题最优解的组成部分,每个子问题的解就是它本身的最优解
重叠子问题
适合用动态规划方法求解的最优化问题,其子问题空间必须足够“小”。如果递归算法反复求解相同的子问题,我们就称最优化问题具有重叠子问题。
重构最优解
维护记录每个子问题最优位置的表,重构时只需O(1)时间。
备忘
在低效的递归算法加入备忘机制可称为自顶向下动态规划法。通常情况下,自底向上动态规划算法没有递归调用的开销,会比自顶向下备忘算法快。但对于某些问题,它的子问题空间中的某些子问题完全不必求解,备忘方法就会体现出优势了,因为它只会求解那些绝对必要的子问题。
15.4 最长公共子序列
public static int lcs(String str1, String str2) { int len1 = str1.length(); int len2 = str2.length(); int c[][] = new int[len1+1][len2+1]; for (int i = 1; i <= len1; i++) { for( int j = 1; j <= len2; j++) { if (str1.charAt(i-1) == str2.charAt(j-1)) c[i][j] = c[i-1][j-1] + 1; else c[i][j] = max(c[i - 1][j], c[i][j - 1]); } } return c[len1][len2];}
15.5 最优二叉搜索树
OPTIMAL-BST(p,q,n)let e[1..n+1,0..n],w[1..n+1,0..n], and root[1..n,1..n] be new tablesfor i = 1 to n+1 e[i,i-1] = q[i-1] w[i,i-1] = q[i-1]for l = 1 to n for i = 1 to n-l+1 j = i+l-1 e[i,j] = \inf w[i,j] = w[i,j-1]+p[j]+q[j] for r = i to j-1 t = e[i,r-1]+e[r+1,j]+w[i,j] if t<e[i,j] e[i,j]=t root[i,j]=rreturn e,root
阅读全文
0 0
- 《算法导论》第15章 动态规划 个人笔记
- 《算法导论》笔记 第15章 15.3 动态规划基础
- 第15章 动态规划 算法导论
- 算法导论代码 第15章 动态规划
- 《算法导论》第15章 动态规划 (1)装配线调度
- 算法导论 第15章 动态规划 装配线调度问题
- 算法导论--第15章 动态规划--钢条切割
- 算法导论 第15章 动态规划之钢条切割
- 算法导论 第15章 动态规划 例程C++实现
- 算法导论 第15章 动态规划 习题C++实现
- 动态规划(算法导论第15章)
- 算法导论第15章 动态规划-装配线调度
- 算法导论第15章 动态规划-矩阵链乘法
- 算法导论第15章 动态规划-总结
- 算法导论:第15章 动态规划_1钢条切割
- 算法导论 第15章 动态规划:15.1钢条切割
- 算法导论 第15章 动态规划:矩阵链乘法
- 算法导论笔记:15动态规划
- Android--混淆
- Android用ImageView显示本地和apache中的图片
- java获取GET和POST请求的URL和参数列表
- 解决ORA-04068 异常existing state of packages has been discarded
- 剑指offer 面试题18 树的子结构
- 《算法导论》第15章 动态规划 个人笔记
- 欧拉函数
- 树莓派从零开始学习记录
- java Map 接口
- Android透明状态栏或者渐变色状态栏
- IO
- Sqlserver_数据库间导数据
- 进程间通信----管道
- Atom 常用快捷键