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

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

分别是Leetcode509/70/746

Leetcode509

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

代码随想录算法训练营day38|动态规划章节_第1张图片

 这道题  按照我们之前递归的思路来说 我们已经知道这道题的递推公式  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])

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