最小花费爬楼梯(动态规划)

给定一个整数数组cost,表示每个台阶的费用,编写一个函数计算达到楼梯顶部的最低花费。可以每次爬一个或两个台阶,从下标0或1开始。使用动态规划方法,创建一个数组minCost存储到达每个台阶的最小花费,最后返回minCost[n]。时间复杂度O(n),空间复杂度O(1)。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。
你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。
请你计算并返回达到楼梯顶部的最低花费。

输入格式:
n 个整数,代表从第 n - 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 的长度为 n,则 n 个阶梯分别对应下标 0 到 n - 1,楼层顶部对应下标 n,问题等价于计算达到下标 n 的最小花费。可以通过动态规划求解。
        创建长度为 n + 1 的数组 minCost,其中 minCost[i] 表示达到下标 i 的最小花费。由于可以选择下标 0 或 1 作为初始阶梯,因此有 minCost[0] = minCost[1] = 0。
        当 2≤i≤n 时,可以从下标 i - 1 使用 cost[i−1] 的花费达到下标 i,或者从下标 i - 2 使用 cost[i−2] 的花费达到下标 i。为了使总花费最小,minCost[i] 应取上述两项的最小值,因此状态转移方程如下:


minCost[i] = min(minCost[i−1] + cost[i−1], minCost[i−2] + cost[i−2])


        依次计算 minCost 中的每一项的值,最终得到的 minCost[n] 即为达到楼层顶部的最小花费。

#include <iostream>
#include <iomanip>
#include <vector>
using namespace std;

int minCostClimbingStairs(vector<int>& cost) {
    //int n = cost.size();
    //int* minCost = new int[n];
    //minCost[0] = minCost[1] = 0;
    //for (int i = 2; i <= n; i++)
    //{
    //    minCost[i] = min(minCost[i - 1] + cost[i - 1], minCost[i - 2] + cost[i - 2]);
    //}
    //return minCost[n];

    int n = cost.size();
    vector<int> minCost(n + 1);              //定义一个到达第 i 层台阶所需的最小花费容器
    minCost[0] = minCost[1] = 0;             //可从第0层和第1层开始,这两层不需要抵达所需花费
    for (int i = 2; i <= n; i++) {
        minCost[i] = min(minCost[i - 1] + cost[i - 1], minCost[i - 2] + cost[i - 2]);
    }
    return minCost[n];                       //返回到达最后一层的最小花费
}

int main() {
    int num;
    vector<int> cost;
    // cost 的长度始终比 i 大,除非输入回车否则输入不会停止(实现输入 n 个整数)
    for (int i = 0; i < cost.size() + 1; i++) {
        cin >> num;
        cost.push_back(num);                  // push.back() 函数,将数据放入 cost
        if (cin.get() == '\n')  break;        //当输入回车的时候退出循环
    }
    cout << minCostClimbingStairs(cost);
    return 0;
}

复杂度分析:
时间复杂度:O(n),其中 n 是数组 cost 的长度。需要依次计算每个 minCost 值,每个值的计算需要常数时间,因此总时间复杂度是 O(n)。
空间复杂度:O(1)。使用滚动数组的思想,只需要使用有限的额外空间。

作者:LeetCode - Solution
链接:https ://leetcode.cn/problems/min-cost-climbing-stairs/solution/shi-yong-zui-xiao-hua-fei-pa-lou-ti-by-l-ncf8/
来源:力扣(LeetCode)
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值