动态规划

动态规划

1. 动态规划的定义

一种数学优化的方法,同时也是编程的方法
在这里插入图片描述

2.重要属性

  1. 最优子结构Optimal Substructure
    • 状态转移方程 f ( n ) f(n) f(n)
  2. 重叠子问题Overlapping Sub-problems
    在这里插入图片描述
    例:最长上升子序列求解
from typing import List


def length_subsquence(nums: List[int]) -> int:
    if not nums:
        return 0
    n = len(nums)
    # # dp[i]表示以第i个元素结尾的最长递增子序列长度,初始值为1
    dp = [1 for _ in range(n)]
    # 遍历每一个元素,求以每一个元素为结尾的最长递增子序列长度
    for i in range(n):
        for j in range(i):
            # 遍历i前面的所有元素,如果nums[j] < nums[i],则求一次dp[i] = max(dp[i],dp[j] + 1)
            if nums[i] > nums[j]:
                dp[i] = max(dp[i], dp[j] + 1)
    return max(dp)

if __name__ == '__main__':
    li = [10, 9, 2, 5, 4, 7, 103]
    res = length_subsquence(li)
    print(res)

3.动态规划结题难点

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

4.动态规划分类

线性规划

  • 各个子问题的规模以线性的方式分布
  • 子问题的最佳状态或结果可以存储在一维线性的数据结构中。例如:一维数组,哈希表
  • 通常我们会用dp[i]表示第i个位置的结果,或者从0开始到第i个位置为止的最佳状态或结果
    基本形式
  • 当前所求的值仅仅依赖于有限个先前计算好的值,即dp[i]仅仅依赖于有限个dp[j],j<i
  • 当前所求的值仅仅依赖于所有先前计算和的值,即dp[i]是各个dp[j]的某种组合,其中j又0遍历到i-1
    例如:斐波那契数列
    区间规划
  • 各个子问题的规模由不同区间来定义
  • 子问题的最佳状态或结果存储在二维数组中
  • 这类问题的时间复杂度一般为多项式时间,即对于一个大小为n的问题,时间复杂度不会超过n的多项式倍数
    约束规划
    在普通的线性规划和区间规划里,一般题目有两种需求:
  • 统计
  • 最优解
    非决定多项式
  • 时间复杂度
    程序运行的时间随着问题规模扩大的增加得有多快
    非多项式级时间复杂度:指数级复杂度,如O( 2 n 2^n 2n),O( 3 n 3^n 3n),全排列算法,复杂度为O( n ! n! n!)
    多项式级时间复杂度
    O( 1 1 1),O( n n n),O( n l o g n nlogn nlogn),O( n 2 n^2 n2),O( n 3 n^3 n3)等
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值