算法训练营Day38(动态规划1)

 动态规划理论基础 

动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的

区别

动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的

例子

动态规划中dp[j]是由dp[j-weight[i]]推导出来的,然后取max(dp[j], dp[j - weight[i]] + value[i]),而贪心呢,每次拿物品选一个最大的或者最小的就完事了,和上一个状态没有关系,所以贪心解决不了动态规划的问题

 知道动规是由前一个状态推导出来的,而贪心是局部直接选最优的,对于刷题来说就够用了

动规五部曲

  1. 确定dp数组(dp table)以及下标的含义
  2. 确定递推公式
  3. dp数组如何初始化
  4. 确定遍历顺序
  5. 举例推导dp数组

509. 斐波那契数 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

提醒

很简单的动规入门题,但简单题使用来掌握方法论的,用动规五部曲来分析。

一、动态规划

class Solution:
    def fib(self, n: int) -> int:
        # 排除 Corner Case
        if n == 0:
            return 0
        # 创建 dp table 
        dp = [0] * (n + 1)
        # 初始化 dp 数组
        dp[0] = 0
        dp[1] = 1
        # 遍历顺序: 由前向后。因为后面要用到前面的状态
        for i in range(2, n + 1):
            # 确定递归公式/状态转移公式
            dp[i] = dp[i - 1] + dp[i - 2]
        # 返回答案
        return dp[n]

二、递归

class Solution:
    def fib(self, n: int) -> int:
        if n < 2:
            return n
        return self.fib(n - 1) + self.fib(n - 2)

70. 爬楼梯   力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

提醒

本题先自己想一想, 之后会发现和 斐波那契数 有点关系。

class Solution:
    def climbStairs(self, n: int) -> int:
        if n <= 1:
            return n
        dp = [0] * (n + 1)
        dp[1] = 1
        dp[2] = 2
        for i in range(3, n + 1):
            dp[i] = dp[i - 1] + dp[i - 2]
        
        return dp[n]

思考

这道题目还可以继续深化,就是一步一个台阶,两个台阶,三个台阶,直到 m个台阶,有多少种方法爬到n阶楼顶。

这又有难度了,这其实是一个完全背包问题,但力扣上没有这种题目,大家可以去卡码网去做一下 57. 爬楼梯

746. 使用最小花费爬楼梯 力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

提醒

明确说 第一步是不用花费的

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        dp = [0] * (len(cost) + 1)
        dp[0] = 0  # 初始值,表示从起点开始不需要花费体力
        dp[1] = 0  # 初始值,表示经过第一步不需要花费体力
        for i in range(2, len(cost) + 1):
            # 在第i步,可以选择从前一步(i-1)花费体力到达当前步,或者从前两步(i-2)花费体力到达当前步
            # 选择其中花费体力较小的路径,加上当前步的花费,更新dp数组
            dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2])
        
        return dp[len(cost)]  # 返回到达楼顶的最小花费

你可能感兴趣的:(算法)