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

目录

题目

思路

题目分析        

动态规划原理

解法一:

1.状态表示biao

2.状态转移方程

3.初始化

4.填表顺序

5.返回值

解法二:

1.状态表示

2.状态转移方程

3.初始化

4.填表顺序

5.返回值

代码

解法一:

解法二:


题目

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)

  • 26
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值