第19课-高级动态规划

小结提纲

  1. 动态规划;递归、分治
  2. 多种情况的动态规划的状态转移方程
  3. 进阶版动态规划

递归、分治、回溯、动态规划

递归 - 函数自己调用自己

public void recur(int level, int param) {
     // terminator
     if (level > MAX_LEVEL) {
       // process result
	   return;
	 }
     // process current logic
     process(level, param);
     // drill down
     recur(level: level + 1, newParam);
     // restore current status
}

分而治之 Divide & Conquer

分治代码模板

def divide_conquer(problem, param1, param2, ...):
  # recursion terminator
  if problem is None:
    print_result
return
  # prepare data
  data = prepare_data(problem)
  subproblems = split_problem(problem, data)
  # conquer subproblems
  subresult1 = self.divide_conquer(subproblems[0], p1, ...)
  subresult2 = self.divide_conquer(subproblems[1], p1, ...)
  subresult3 = self.divide_conquer(subproblems[2], p1, ...)
  ...
  # process and generate the final result
  result = process_result(subresult1, subresult2, subresult3, ...)
  # revert the current level states

感触

  1. 人肉递归低效、很累
  2. 找到最近最简方法,将其拆解成可重复解决的问题
  3. 数学归纳法思维

本质:寻找重复性 —> 计算机指令集

递归状态树
在这里插入图片描述

Fib(6) 状态树、重复子状态
在这里插入图片描述

动态规划 Dynamic Programming

  1. “Simplifying a complicated problem by breaking it down into simpler sub-problems”
    (in a recursive manner)
  2. Divide & Conquer + Optimal substructure 分治 + 最优子结构
  3. 顺推形式: 动态递推

DP 顺推模板

function DP():
dp = [][] # 二维情况
  for i = 0 .. M {
    for j = 0 .. N {
       dp[i][j] = _Function(dp[i’][j’]...)
    }
  }
  return dp[M][N];

关键点

动态规划 和 递归或者分治 没有根本上的区别(关键看有无最优的子结构)
拥有共性:找到重复子问题

差异性:最优子结构、中途可以淘汰次优解

常见的 DP 题目和状态方程

爬楼梯

在这里插入图片描述

不同路径

在这里插入图片描述

打家劫舍

在这里插入图片描述

最小路径和

在这里插入图片描述

股票买卖

https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/

https://leetcode-cn.com/problems/best-time-to-buy-and-sell-stock/solution/yi-ge-fang-fa-tuan-mie-6-dao-gu-piao-wen-ti-by-l-3/

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

高阶的 DP 问题

复杂度来源

  1. 状态拥有更多维度(二维、三维、或者更多、甚至需要压缩)
  2. 状态方程更加复杂

本质:内功、逻辑思维、数学

爬楼梯问题改进

• 1、2、3
• x1, x2, …, xm 步
• 前后不能走相同的步伐

Homework:

https://leetcode-cn.com/problems/min-cost-climbing-stairs/

编辑距离

  • 如果 word1[i] 与 word2[j] 相同,显然 dp[i][j]=dp[i-1][j-1]
  • 如果 word1[i] 与 word2[j] 不同,那么 dp[i][j] 可以通过
    • 1 在 dp[i-1][j-1] 的基础上做 replace 操作达到目的
    • 2 在 dp[i-1][j] 的基础上做 insert 操作达到目的
    • 3 在 dp[i][j-1] 的基础上做 delete 操作达到目的

取三者最小情况即可

Homework

  1. https://leetcode-cn.com/problems/longest-increasing-subsequence/

  2. https://leetcode-cn.com/problems/decode-ways/

  3. https://leetcode-cn.com/problems/longest-valid-parentheses/

  4. https://leetcode-cn.com/problems/maximal-rectangle/

  5. https://leetcode-cn.com/problems/distinct-subsequences/

  6. https://leetcode-cn.com/problems/race-car/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值