算法刷题打卡033 | 动态规划1

理论基础

动态规划的应用前提是有重叠子问题,通过子问题状态推导获得问题的最终解。第二次做动态规划的题了,希望这次能对动态规划有更透彻的理解。

LeetCode 509 斐波那契数

题目链接:509. 斐波那契数 - 力扣(Leetcode)

斐波那契数列是经典动态规划入门题,但其实根据题目描述进行模拟也可以解题:

class Solution:
    def fib(self, n: int) -> int:
        if n == 0:
            return 0
        dp1, dp2 = 0, 1
        for i in range(2, n+1):
            dp = dp1 + dp2
            dp1 = dp2
            dp2 = dp
        return dp2

 关键是帮助理解怎么进行动态规划相关解题过程。

LeetCode 70 爬楼梯

题目链接:70. 爬楼梯 - 力扣(Leetcode)

爬楼梯也是最简单的动态规划之一了,一刷时理解了原理和状态推导,子问题方法数本质上就是斐波那契数列,再看题就自然而然AC了:

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

            dp1 = dp2
            dp2 = dp
        return dp

LeetCode 746 使用最小花费爬楼梯

题目链接:746. 使用最小花费爬楼梯 - 力扣(Leetcode)

 一开始做这道题可能会对楼顶这个概念存疑,比如到底哪个下标指楼顶?到楼顶是必须到达那个下标,还是最后一步上楼的范围覆盖楼顶即可?个人理解楼顶是指下标为n的位置(也就是第n阶楼梯,数组下标最多为n-1),和爬楼梯一样,到达第i阶楼梯有两种选择,一是从第i-1阶楼梯跨一步上来,二是从第i-2阶楼梯跨两步上来,要得到最小的cost,就应该选择其中花费较小的方式。dp[i]表示到达第i阶楼梯并且继续从需要的最小花费,只要还没到达楼顶,就还需要从当前台阶往上走,必须花费掉当前的cost[i]。基于当前设定,dp数组初始化的dp1和dp2直接初始化为cost[0]和cost[1](到达0下标和1下标的台阶不需要花费,他们的dp就是从0/1出发所需花费)。

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        n = len(cost)
        if n == 2:
            return min(cost[0], cost[1])
        dp1, dp2 = cost[0], cost[1]
        for i in range(2, n):
            dp = min(dp1, dp2) + cost[i]
            dp1 = dp2
            dp2 = dp
        return min(dp1, dp2)

你可能感兴趣的:(刷题,算法,动态规划,leetcode)