动态规划|【斐波那契数列模型 】|746.使用最小花费爬楼梯

简介: 动态规划|【斐波那契数列模型 】|746.使用最小花费爬楼梯



题目

746. 使用最小花费爬楼梯

提示

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

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

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

示例 1:

输入:cost = [10,15,20]

输出:15

解释:你将从下标为 1 的台阶开始。

- 支付 15 ,向上爬两个台阶,到达楼梯顶部。

总花费为 15 。


示例 2:

输入:cost = [1,100,1,1,1,100,1,1,100,1]

输出:6

解释:你将从下标为 0 的台阶开始。

- 支付 1 ,向上爬两个台阶,到达下标为 2 的台阶。

- 支付 1 ,向上爬两个台阶,到达下标为 4 的台阶。

- 支付 1 ,向上爬两个台阶,到达下标为 6 的台阶。

- 支付 1 ,向上爬一个台阶,到达下标为 7 的台阶。

- 支付 1 ,向上爬两个台阶,到达下标为 9 的台阶。

- 支付 1 ,向上爬一个台阶,到达楼梯顶部。

总花费为 6 。



提示:

  • 2 <= cost.length <= 1000
  • 0 <= cost[i] <= 999

思路

题目分析        

       此题他说给一个数组,这个数组里面的值是代表每级台阶向上爬的费用,每次在相应台阶支付费用,可以选择爬一层台阶或者两层台阶,题目要求计算到达楼梯顶部所花的费用,既然要计算到达楼梯顶部所花费的费用,首先我们得知道楼梯顶部在哪?根据给定cost数组:题目中说cost[i]代表第i级台阶向上爬所需要的费用,因为楼梯顶部是不需要往上爬的,所以也没有支付费用 ,,根据所给的示例,对于示例1,cost有三位数,从第四项开始就没有支付费用,所以第四项也就是下标为三数,是楼梯顶部,类比示例2,cost有九级台阶,所以第十项就是楼梯顶部

       另外,题目中说我们可以选择从0级台阶爬,也可以从1级台阶开始爬,这个也是根据最省钱的方案选择(如果从0级台阶爬,最省钱就选从0级台阶开始,如果从1级台阶爬最省钱就从1级台阶开始爬).

动态规划原理

解法一:

1.状态表示biao

       dp表里面的值表示的含义就是一个状态表示。

       本题就是,dp[i]表示,到达第i个台阶的最小花费

2.状态转移方程

        状态转移方程就是:dp[i]等于什么?一般情况下就是使用dp[i]前的状态或者(dp[i-1],dp[i-2]...)dp[i]后面的状态(dp[i+1],dp[i+2]...)推导出转移状态方程.那么怎么到达dp[i]呢,根据题目描述,支付后选择向上爬一个台阶,或者爬两个台阶,

a) 爬一个台阶,先到达i-1位置,支付cost[i-1],向上爬一个台阶

b) 爬两个台阶,先到达i-2位置,支付cost[i-2],向上爬两个台阶

cost[i-1]和cost[i-2]是一个定值,因此,到达i要花费最小,就是要到达i-1最小,到达i-2最小

根据上面状态表示的定义“dp[i]表示,到达第i个台阶的最小花费”所以到达i-1最小花费dp[i-1],到达dp[i-2]最小花费就是dp[i-2],

根据以上分析,状态转移方程

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

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

最后将两种情况对比,之后取最小值。

3.初始化

        初始化就是:保证填表的时候不越界,对该初始化的值要进行初始化

        因为可以直接从第0级台阶和第1台阶开始不需要花钱,所以dp[0]=dp[1]=0

4.填表顺序

       确定填表顺序是为了填写当前状态时,所需要的状态已经计算过了

       因为算dp[i]时,所以只能先算前面(dp[i-1],dp[i-2])的,填表顺序就是从左往右

5.返回值

       根据题目要求(到达i时所需要的最小花费)和状态表示返回我们要的答案

       本题就是dp[n]

解法二:

1.状态表示

还是创建一个dp表

于解法一不同的是,这次的dp[i]表示,i位置到达楼顶的最小花费

2.状态转移方程

分析到达楼顶的最小花费的形成过程,因为dp[i]表示i位置到达楼顶的最小花费,说明此时已经 到达了第i级台阶,支付cost[i]后

a)走一步到达第i+1级台阶,再从i+1的位置走到顶部,

b)走两步到达第i+2级台阶,再从i+2的位置走到顶部

要到达顶部的花费最小,就需要让i+1到顶部最小,根据状态表示,就可以把i+1到顶部最小表示为dp[i+1],同理i+2到顶部最小表示为dp[i+2]

所以状态转移方程可以表示为

dp[i]=cost[i]+dp[i+1]

dp[i]=cost[i]+dp[i+2]

然后就是两种情况比较,取最小值

3.初始化

       因为要用到后两个位置,所以要初始化倒数第一个台阶到顶部的最小花费,和倒数第二个台阶到顶部的最小花费,dp[n-1]=cost[n-1],dp[n-2]=cost[n-2]

4.填表顺序

       观察状态转移方程看出,由后面的值得出前面的值,所以填表顺序就是 从后往前

5.返回值

       我们的状态表示,dp[i]表示第i台阶到顶部的最小花费,根据题目要求的是-到达i时所需要的最小花费,也就是开始到顶部的最小花费,开始我们可以从 0开始,也可以从1开始,所以返回dp[0]和dp[1]两者的较小值。

代码

还是原来的四步

1.创建dp表

2.初始化

3.填表顺序

4.返回答案

解法一:

int minCostClimbingStairs(int* cost, int costSize) {
    //创建dp表
    int dp[10000]={0};
    //初始化
    dp[0]=dp[1];
    //填表
    for(int i=2;i<=costSize;i++)
    {
        dp[i]=(dp[i-1]+cost[i-1]<dp[i-2]+cost[i-2])?dp[i-1]+cost[i-1]:dp[i-2]+cost[i-2];
    }
    //返回
    return dp[costSize];
}

空间复杂度:O(n)

时间复杂度:O(n)

解法二:

int minCostClimbingStairs(int* cost, int costSize) {
    //创建dp表
    int dp[10000]={0};
    //初始化
    dp[costSize-1]=cost[costSize-1];
    dp[costSize-2]=cost[costSize-2];
    //填表
    for(int i=costSize-3;i>=0;i--)
    {
        dp[i]=(dp[i+1]+cost[i]<dp[i+2]+cost[i])?dp[i+1]+cost[i]:dp[i+2]+cost[i];
    }
    //返回
    return (dp[0]>dp[1])?dp[1]:dp[0];
}

空间复杂度:O(n)

时间复杂度:O(n)

相关文章
|
7月前
|
算法
【动态规划专栏】专题一:斐波那契数列模型--------3.最小花费爬楼梯
【动态规划专栏】专题一:斐波那契数列模型--------3.最小花费爬楼梯
58 2
|
7月前
|
算法 JavaScript Java
【状态压缩】【动态规划】【C++算法】1125.最小的必要团队
【状态压缩】【动态规划】【C++算法】1125.最小的必要团队
|
7月前
leetcode代码记录(使用最小花费爬楼梯
leetcode代码记录(使用最小花费爬楼梯
40 0
|
7月前
动态规划之使用最小花费爬楼梯【LeetCode】
动态规划之使用最小花费爬楼梯【LeetCode】
|
7月前
代码随想录Day32 动态规划01 LeetCodeT509 斐波那契数列 T70 爬楼梯 T746 爬楼梯的最小消耗
代码随想录Day32 动态规划01 LeetCodeT509 斐波那契数列 T70 爬楼梯 T746 爬楼梯的最小消耗
50 0
|
7月前
|
Java 索引
leetcode-746:使用最小花费爬楼梯
leetcode-746:使用最小花费爬楼梯
52 0
【动态规划入门】动态规划思路五部曲_斐波那契_爬楼梯_最小花费爬楼梯
【动态规划入门】动态规划思路五部曲_斐波那契_爬楼梯_最小花费爬楼梯
74 0
|
算法
【学会动态规划】使用最小花费爬楼梯(3)
【学会动态规划】使用最小花费爬楼梯(3)
108 1
算法训练Day38|● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯
算法训练Day38|● 509. 斐波那契数 ● 70. 爬楼梯 ● 746. 使用最小花费爬楼梯
|
测试技术
动态规划之使用最小花费爬楼梯
动态规划之使用最小花费爬楼梯
下一篇
DataWorks