代码随想录算法训练营day38 | 动态规划: 理论基础,509. 斐波那契数,70. 爬楼梯,746. 使用最小花费爬楼梯

动规五部曲:

  1. dp数组

  2. 递推公式

  3. 初始化

  4. 遍历顺序

  5. 打印检查

509. 斐波那契数

  • 自己写的没什么套路的ac

class Solution:
    def fib(self, n: int) -> int:
        if n == 0:
            return 0
        
        ans = [0]*(n+1)
        ans[0] = 0
        ans[1] = 1
        print(ans)
        for i in range(2, n+1):
            ans[i] = ans[i-1]+ans[i-2]
        print(ans)
        return ans[-1]
  • 其他的两种解法:

class Solution:
    def fib(self, N: int) -> int:
        if N<=1:
            return N
        return self.fib(N-1)+self.fib(N-2)
class Solution:
    def fib(self, N):
        """
        :type N: int
        :rtype: int
        """
        a,b=0,1
        for x in range(N):
            a,b = b,a+b
        return a
  • Carl模版解法:实际上第一种写法就是按照动归五部曲来进行的,只是没有意识到

class Solution:
    def fib(self, n: int) -> int:
        if n == 0:
            return 0
        #step1: dp数组以及dp[i]的含义:第i个斐波那契数的值
        dp = [0]*(n+1)
        #step2: 递推公式: dp[i] = dp[i-1]+dp[i-2]
        #step3: 初始化
        dp[0] = 0
        dp[1] = 1
        #step4: 遍历顺序
        for i in range(2, n+1):
            dp[i] = dp[i-1]+dp[i-2]
        #step5: 打印检查
        return dp[n]

70. 爬楼梯​​​​​​

关键点:(Carl视频讲解留言板)

题目中要求的每次可以爬1或者2个台阶,也就是说,最终到达n阶台阶有两种方式,一个是爬1阶台阶到达(对应的是从n-1阶台阶开始),那么另一个就是爬2阶台阶到达(对应的是从n-2阶台阶开始爬),而爬n-1阶和n-2阶台阶的方法有dp【n-1】,dp【n-2】个。所以最终爬n阶台阶的方法种类就是dp【n-1】+dp【n-2】。其实也对应了卡尔所说的从n-1和n-2阶爬上去,探究的是几种走法,而不是几步。

class Solution:
    def climbStairs(self, n: int) -> int:
        if n <= 1:
            return n
        #step1: dp[i]是指到达第i阶有dp[i]种方法
        dp = [0]*(n+1)
        #step2: 递推公式: dp[i] = dp[i-2] + dp[i-1]
        #step3:初始化
        '''
        为什么不初始化为dp[0]=0, dp[1]=1,这样也能ac?
        因为题目限制1<=n<=45,也就是说n不会是0,那么dp[0]含义就没有意义,这样就需要初始化后面两项
        '''
        dp[1] = 1
        dp[2] = 2
        #step4: 遍历顺序
        for i in range(3, n+1):
            dp[i] = dp[i-2] + dp[i-1]
        #step5: 打印检查
        return dp[n]

remark:

  • 也可以按照题解的方法进行优化,从而空间复杂度为O(1)。但实际原理一样

746. 使用最小花费爬楼梯

五部曲一定要明确

class Solution:
    def minCostClimbingStairs(self, cost: List[int]) -> int:
        if len(cost) == 1:
            return cost[0]
        #step1: dp[i]是到达第i个台阶所花费的最少体力为dp[i](包括当前台阶的体力值,对应cost[i])
        dp = [0]*len(cost)
        #step2: 递推公式: dp[i] = min(dp[i-1], dp[i-2]) + cost[i]
        #step3: 初始化
        dp[0] = cost[0]
        dp[1] = cost[1]
        #step4: 遍历顺序
        for i in range(2, len(cost)):
            dp[i] = min(dp[i-1], dp[i-2]) + cost[i]
        #step5: 打印检查
        return min(dp[len(cost)-1], dp[len(cost)-2])

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值