第33天|509. 斐波那契数、70. 爬楼梯、746. 使用最小花费爬楼梯

文章介绍了动态规划的常见题型,包括斐波那契数、路径问题、背包问题等,并详细讲解了动态规划的五个基本步骤。通过两个具体的例子——斐波那契数列和爬楼梯问题,展示了如何运用动态规划解题,特别强调了数组初始化和避免越界问题的重要性。此外,还讨论了涉及成本的爬楼梯问题,要求找到最小花费的解决方案。
摘要由CSDN通过智能技术生成

1.动态规划常见题型:

                                                        ①斐波那契

                                                        ②路径问题

                                                        ③背包问题

                                                        ④打家劫舍

                                                        ⑤股票问题

                                                        ⑥子序列问题

2.动态规划步骤:

                                        1.明确dp[i]的含义及下标含义

                                        2.求递推公式

                                        3.根据递推公式和题意确定如何初始化数组

                                        4.确定遍历顺序

                                        5.如果有bug,将dp数组打印出来debug

3.题目链接:509. 斐波那契数

题目描述:

                斐波那契数 (通常用 F(n) 表示)形成的序列称为 斐波那契数列 。该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和。也就是:

                F(0) = 0,F(1) = 1
                F(n) = F(n - 1) + F(n - 2),其中 n > 1
                给定 n ,请计算 F(n) 。

解法1维护数组:

                1.思路五部曲:

                        ①首先明确dp[i] --- 表示的是第i个位置的斐波那契数

                        ②递推公式 --- dp[i] = dp[i-2] + dp[i-1]

                        ③dp初始化 --- 根据题意dp[0] = 0,dp[1] = 1

                        ④遍历顺序 --- 因为是根据前两个的值得到当前值,所以按顺序遍历

                2.步骤:

                        ①故先定义一个dp数组,长度为n+1,因为有0有n所以长度为n+1

                        ②初始化dp[0] = 0, dp[1] = 1

                        ③顺序遍历for(i=2~n){递推公式}

                        ④最后返回数组中最后一个值。

                        ⑤要注意的是要在最前面写if(n<2){return n;} --- 可能会想,下面不是都初始化了0,和1对应的值吗?为什么还要特殊写,因为如果不写的话在定义dp数组的时候,如果n = 0,那么数组的长度就是1,无法定义dp[1],就会出现索引越界的问题,所以一定要写。

解法2维护三个数:

                可以将上面维护数组的动作压缩成只维护三个变量,即dp[i-2],dp[i-1],dp[i].用a,b,c分别对应,即a = 0,b = 1,c = 0。然后在for循环中{c = a+b, a = b, b = c},最后返回c。

下面为代码(java):

 

4.题目链接:70. 爬楼梯 

题目描述:

                假设你正在爬楼梯。需要 n 阶你才能到达楼顶。

                每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?

解法:

                1.思路5步曲:

                        ①首先明确dp[i]表示的是,共有i个阶,有 dp[i]种方法爬到楼顶。

                        ②递推公式:当i  =1,有1种。当i=2,有2种,当i=3,有3种(怎么求的呢?当有3个台阶,上一个必须在其上一个或者上两个,因为每次只能爬1个或者2个台阶)故3 =1+2。所以递推公式就是,dp[i] = dp[i-1] + dp[i-2].

                        ③初始化:根据递推公式可以发现,整个数组的基础就是前两个值,所以初始化前两个即可。即dp[1] = 1,dp[2] = 2.此处的dp[0]没有意义,即没有台阶那么要么理解成直接站到最终位置了需要0种方法,要么理解成1种方法---但题目中说了n>0所以这个赋值是没有意义的,但是这样初始化代码好写,我们不这样写,采取不赋值的写法

                        ④遍历顺序:根据递推公式,需要前面的值来求当前值,所以顺序遍历。

                2.步骤:

                        ①即初始化dp,长度为n+1,因为规定问题,虽然我们只需要n个元素,但是数组下标从0开始,所以长度为n+1

                        ②初始化---dp[1] = 1,dp[2] =2

                        ③顺序遍历---for(i=2开始~n){dp[i] = dp[i-2] + dp[i-1];}

                        ④最后返回dp[n].

                        ⑤要注意同样的越界问题,在最上面要写if(n<=2)|| if(n==1),{return n}这两种都不会越界。

                        ⑥当然也可以进行压缩,只维护三个变量。

下面为代码(java):

 

4.题目链接:746. 使用最小花费爬楼梯 

题目描述:

                给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。

                你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。

                请你计算并返回达到楼梯顶部的最低花费

解法:

                1.思路五步曲:

                        ①明确dp[i]表示的是到第i个台阶需要的最低花费,因为cost[i]表示的是从楼梯第 i 个台阶向上爬需要支付的费用,所以当走到cost数组的最后一个位置之后再向上走一步才是楼顶,所以dp数组的长度应该是cost长度+1.

                        ②递推公式:dp[i]只能由dp[i-1]或者dp[i-2]向上跳。因为每次只能跳一步或者跳两步,而又要求最小花费,故dp[i] = min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2])

                        ③初始化:根据递推公式,整个数组的基础就是前两个值,所以初始化dp[0],dp[1]。而题目中说可以选择从0位置或者1位置开始爬,故dp[0] =0 ,dp[1] = 1

                        ④遍历顺序:根据递归公式,要通过前面的值获取当前值,所以呢要顺序遍历。

                2.步骤:

                        ①构建dp数组,长度为cost长度+1

                        ②初始化dp[0] = 0,dp[1] =0

                        ③for(i=2~cost.length+1){递归公式}

                        ④最后返回数组中最后一个值即dp[dp.length-1] 

                        ⑤因为此题中cost的长度>=2,所以不用特殊情况处理,在初始化和下面循环的时候,不会越界。

下面为代码(java):

5.总结:

                ①动态规划入门,有5步曲,按5步分析可以贯彻整个dp篇。

                ②斐波那契数题目中要注意的就是,容易造成索引越界,所以在初始的时候要判断特殊的情况,防止越界。

                ③爬楼梯本质上就是斐波那契,也要注意越界问题,第三题中cost的长度保证了不会越界。 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值