代码随想录算法训练营day38|动态规划章节

本文通过动态规划解析LeetCode中的509斐波那契数、70爬楼梯和746使用最小花费爬楼梯问题。针对每个问题,详细阐述了动态规划的五部曲,包括确定dp数组、递推公式、初始化、遍历顺序和实例推导,并提供了Python代码实现。对于爬楼梯问题,讨论了dp[0]初始化的不同观点,提出了不考虑dp[0]的方案。
摘要由CSDN通过智能技术生成

今天从懂太规划的入门篇开始

分别是Leetcode509/70/746

Leetcode509

509. 斐波那契数 - 力扣(Leetcode)

 这道题  按照我们之前递归的思路来说 我们已经知道这道题的递推公式  f(n) = f(n-1)+f(n-2)。

确定动态规划五部曲:

1.确定dp数组以及下标的含义

dp[i]的定义为:第i个数的斐波那契数值是dp[i]


 

2.确定递推公式

dp[i] = dp[i-1]+dp[i-2]

3.数组如何初始话

dp[0] = 0

dp[1] = [1]

4.确定遍历顺序

从递归公式dp[i] = dp[i - 1] + dp[i - 2]中可以看出,

dp[i]是依赖 dp[i - 1] 和 dp[i - 2],

那么遍历的顺序一定是从前到后遍历的

5.举例推导dp数组

按照这个递推公式dp[i] = dp[i - 1] + dp[i - 2],

我们来推导一下,当N为10的时候,dp数组应该是如下的数列:

0 1 1 2 3 5 8 13 21 34 55

如果代码写出来,发现结果不对,

就把dp数组打印出来看看和我们推导的数列是不是一致的。

       

这里我就用python的写法 

a,b,c来代替dp数组 然后相互交换 

def fib(self, n: int) -> int:
        if n<2:
            return n 
        a = 0 
        b = 1 
        c = 0 
        for i in range(1,n):
            c = a+b  
            a,b = b,c  
        return c

这里c的作用是用来保存前两个相加的和

a代表dp[0],b代表dp[1]

Leetcode70爬楼梯

力扣

这道题 经过我 多次画图验证的出 

爬1个阶梯 有1种方法

爬2个阶梯 有2种方法

爬3个阶梯 有3种方法

爬4个阶梯 有5种方法

从这个例子可以看出来 爬第n层楼的阶梯有几种方法是由前两个方法相加 也就是第n-1个阶梯的方法+n-2个阶梯的方法相加得出

注意!!!!这里是找方法而不是找爬到第几阶梯需要的步数

 其次就是 我们既然已经知道了递推公式 

那么有一个问题在这里了,如果i = 0 ,也就是当我们在第0层的时候,我们的dp[0]应该初始化为多少呢,是0还是1呢?

这个可以有很多解释,但都基本是直接奔着答案去解释的。

例如强行安慰自己爬到第0层,也有一种方法,什么都不做也就是一种方法即:dp[0] = 1,相当于直接站在楼顶。

但总有点牵强的成分。

那还这么理解呢:我就认为跑到第0层,方法就是0啊,一步只能走一个台阶或者两个台阶,然而楼层是0,直接站楼顶上了,就是不用方法,dp[0]就应该是0.

其实这么争论下去没有意义,大部分解释说dp[0]应该为1的理由其实是因为dp[0]=1的话在递推的过程中i从2开始遍历本题就能过,然后就往结果上靠去解释dp[0] = 1

从dp数组定义的角度上来说,dp[0] = 0 也能说得通。

需要注意的是:题目中说了n是一个正整数,题目根本就没说n有为0的情况。

所以本题其实就不应该讨论dp[0]的初始化!

我相信dp[1] = 1,dp[2] = 2,这个初始化大家应该都没有争议的。

所以我的原则是:不考虑dp[0]如果初始化,只初始化dp[1] = 1,dp[2] = 2,然后从i = 3开始递推,这样才符合dp[i]的定义。

代码:

def climbStairs(self, n: int) -> int:
        #递归实现
        # if n==0 or n==1:
        #     return 1
        # return self.climbStairs(n-1) + self.climbStairs(n-2)
        
        """动态规划实现"""
        #当n = 0 or 1 的时候都返回是1 
        dp = [0] * (n+1)
        dp[0] = 1
        dp[1] = 1 
        for i in range(2,n+1):
            dp[i] = dp[i-1] + dp[i-2]
        return dp[n]

Leetcode746使用最小花费爬楼梯 

力扣

EMMMMM,这道题出的很好。。下次建议换个出题人 

运用动态规划来解决这道题,说实话到现在我都是懵逼的,读不懂题意,爬个楼梯还要给钱??

这里代码先放了

欢迎各位大佬来指点一下

def minCostClimbingStairs(self, cost: List[int]) -> int:
        dp = [0] * (len(cost))
        dp[0] = cost[0]
        dp[1] = cost[1]
        for i in range(2, len(cost)):
            dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]
        return min(dp[len(cost) - 1], dp[len(cost) - 2])

代码随想录算法训练营是一个优质的学习和讨论平台,提供了丰富的算法训练内容和讨论交流机会。在训练营中,学员们可以通过观看视频讲解来学习算法知识,并根据讲解内容进行刷题练习。此外,训练营还提供了刷题建议,例如先看视频、了解自己所使用的编程语言、使用日志等方法来提高刷题效果和语言掌握程度。 训练营中的讨论内容非常丰富,涵盖了各种算法知识点和解题方法。例如,在第14天的训练营中,讲解了二叉树的理论基础、递归遍历、迭代遍历和统一遍历的内容。此外,在讨论中还分享了相关的博客文章和配图,帮助学员更好地理解和掌握二叉树的遍历方法。 训练营还提供了每日的讨论知识点,例如在第15天的讨论中,介绍了层序遍历的方法和使用队列来模拟一层一层遍历的效果。在第16天的讨论中,重点讨论了如何进行调试(debug)的方法,认为掌握调试技巧可以帮助学员更好地解决问题和写出正确的算法代码。 总之,代码随想录算法训练营是一个提供优质学习和讨论环境的平台,可以帮助学员系统地学习算法知识,并提供了丰富的讨论内容和刷题建议来提高算法编程能力。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [代码随想录算法训练营每日精华](https://blog.csdn.net/weixin_38556197/article/details/128462133)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值