动态规划 - 746. 使用最小花费爬楼梯(C#和C实现)

746. 使用最小花费爬楼梯

题目描述

数组的每个下标作为一个阶梯,第 i 个阶梯对应着一个非负数的体力花费值 cost[i](下标从 0 开始)。

每当你爬上一个阶梯你都要花费对应的体力花费值,然后你可以选择继续爬一个阶梯或者跳过这个阶梯。请你找出达到楼层顶部的最低花费。

在开始时,你可以选择从索引为 01 的元素作为初始阶梯。

示例 1:

输入:cost = [10, 15, 20]
输出:15
解释:最低花费是从 cost[1] 开始,然后走两步,一共花费 15

示例 2:

输入:cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
输出:6
解释:最低花费是从 cost[0] 开始,然后走两步,一共花费 6

提示:

  • cost 的长度范围是 [2, 1000]
  • cost[i] 将会是一个整型数据,范围为 [0, 999]

解题思路

动态规划
  1. 定义状态:dp[i] 表示从第 i 个阶梯出发,达到楼层顶部的最低花费。
  2. 状态转移方程: dp[i] = cost[i] + min(dp[i-1], dp[i-2]),即从第 i 个阶梯出发的最低花费等于当前阶梯的花费加上前两个阶梯中最低花费的那个。
  3. 初始状态: dp[0] = cost[0]dp[1] = cost[1]
  4. 遍历顺序: 从小到大遍历,计算每个阶梯的最低花费。
特殊案例
  • 如果输入 cost 的长度为 2,则直接返回 min(cost[0], cost[1])

C#代码实现

public int MinCostClimbingStairs(int[] cost) {
    // 定义变量n,表示cost数组的长度
    int n = cost.Length;

    // 如果cost数组的长度为2,则直接返回cost数组中两个元素的最小值
    if (n == 2) {
        return Math.Min(cost[0], cost[1]);
    }

    // 定义变量dp,长度为n,用于存储状态
    int[] dp = new int[n];
    // 初始化dp数组,dp[0]表示爬到第一阶楼梯的最小花费,dp[1]表示爬到第二阶楼梯的最小花费
    dp[0] = cost[0];
    dp[1] = cost[1];

    // 从第三阶楼梯开始,动态规划计算最小花费
    for (int i = 2; i < n; i++) {
        // dp[i]表示爬到第i阶楼梯的最小花费
        dp[i] = cost[i] + Math.Min(dp[i - 1], dp[i - 2]);
    }

    // 返回爬到第n阶楼梯的最小花费
    return Math.Min(dp[n - 1], dp[n - 2]);
}

C代码实现

int minCostClimbingStairs(int* cost, int costSize) {
    // 如果楼梯只有两阶,则直接返回最小成本
    if (costSize == 2) {
        return fmin(cost[0], cost[1]);
    }

    // 动态规划,dp[i]表示到第i阶楼梯的最小成本
    int* dp = (int*)malloc(sizeof(int) * costSize);
    dp[0] = cost[0];
    dp[1] = cost[1];

    // 从第二阶楼梯开始,动态规划计算最小成本
    for (int i = 2; i < costSize; i++) {
        dp[i] = cost[i] + fmin(dp[i - 1], dp[i - 2]);
    }

    // 返回最后两阶楼梯的最小成本
    int result = fmin(dp[costSize - 1], dp[costSize - 2]);
    free(dp);

    return result;
}

时间复杂度和空间复杂度

  • 时间复杂度:O(n),其中 n 是 cost 数组的长度。需要计算每个阶梯的最低花费。
  • 空间复杂度:O(n)。使用了一个大小为 n 的数组来保存中间结果。

参与点评

读者朋友们,如果您在阅读过程中,对文章的质量、易理解性有任何建议,欢迎在评论区指出,我会认真改进。

  • 18
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AmHardy

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值