动态规划学习(35分钟视频课)

1、定义

一种数学优化的方法,同时也是编程的方法。

重要属性:

  • 最优子结构 Optimal Substructure
      • 状态转移方程f{n}
  • 重叠子问题(Overlapping Sub-problems)

必须满足以上两个属性才可以归为动态规划问题。

2、例题讲解

2.1、例题1 引入

要求从A到C的最长路径,要求,每个顶点只能出现一次。
1
A到C的最长距离

  • A->B->C
    • A 到 B的最长距离
    • B 到 C的最长距离

最后有一条路径出来了

A->D->C->B->A->D->C

对于这道题而言,没有最佳子结构,所以无法利用动态规划来解题。

2.2、例题2 LeetCode第300题

2.2.1、动态规划方法

题目描述:
给定一个无序的整数数组,找到其中最长上升子序列的长度。
示例:
输入: [10,9,2,5,3,7,101,18]
输出: 4
解释: 最长的上升子序列是 [2,3,7,101],它的长度是 4。
说明:
可能会有多种最长上升子序列的组合,你只需要输出对应的长度即可。
你算法的时间复杂度应该为 O(n2) 。
进阶: 你能将算法的时间复杂度降低到 O(n log n) 吗?

思路:将问题规模减少,推导出状态转移方程式

2
来几个直观的图片:
3
那么这一题,状态转移方程怎么推导呢?
4
到这里,已经可以证明这个问题是存在最优子结构的,我们继续分析。(emmm这里还有点不懂)
5

2.2.2、公式法

6
通过观察得到:
7
复杂度太高,放弃。

2.2.3、记忆化

8
时间复杂度分析:
9
对于这种将问题规模不断减少的做法,我们把它称为自顶向下的方法。

换一种自底向上的方法吧,

10
老规矩,我们来分析一下时间复杂度吧!
11

3、动态规划解题难点

  • 应该采用什么样的数据结构来保存什么样的计算结果
  • 如何利用保存下来的计算结果推导出状态转移方程

3.1、线性规划

  1. 线性规划
    • 各个子问题的规模以线性的方式分布。
    • 子问题的最佳状态或结果可以存储在一维线性的数据结构中,例如:一维数组,哈希表等。
    • 通常我们会用dp[i]表示第i个位置的结果,或者从0开始到第i个位置为止的最佳状态或结果。

12
题目:
13
求出递归公式:
14
代码实现:

public int rob(int[] nums) {
    int n = nums.length;
  
    // 处理当数组为空或者数组只有一个元素的情况
    if(n == 0) return 0;
    if(n == 1) return nums[0];

    // 定义一个 dp 数组,dp[i] 表示到第 i 个元素为止我们所能收获到的最大总数
    int[] dp = new int[n];

    // 初始化 dp[0],dp[1]
    dp[0] = nums[0];
    dp[1] = Math.max(nums[0], nums[1]);

    // 对于每个 nums[i],考虑两种情况,选还是不选,然后取最大值
    for (int i = 2; i < n; i++) {
        dp[i] = Math.max(nums[i] + dp[i - 2], dp[i - 1]);
    }
  
    return dp[n - 1];
}

LeetCode第62题
14

3.2、区间规划

各个子问题的规模由不同区间来定义
子问题的最佳状态或结果可以存储在为二维数组中
这类问题的时间复杂度一般为多项式时间,即对于一个大小为n的问题,时间复杂度不会超过n的多项式倍数。

最长回文子序列
给定一个字符串s,找到其中最长的回文子序列。
可以假设s的最大长度为1000。

递归公式,
15
16

3.3、约束规划

在普通的线性规划里,一般题目有两种需求:

  • 统计
  • 最优解

例题:0-1背包问题
给定n个物品,每个物品有各自的价值v和重量w,在限定的最大重量内,我们如何选择,才能使被带走的物品的价值总和最大?

这题自己做一遍。
17

18

学习动态规划没有捷径,更重要的是多练!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值