LC.746 使用最小花费爬楼梯

本文解析了如何修正错误的dp定义,以正确地使用动态规划解决经典的爬楼梯问题。通过实例演示了如何定义dp数组,推导状态转移方程,并强调了dp数组在算法中的关键作用。

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

题目描述:

解法:

class Solution {

    public int minCostClimbingStairs(int[] cost) {

        int n = cost.length;

        int[] dp = new int[n];

        dp[0] = cost[0];

        dp[1] = cost[1];

        for(int i = 2; i < n; i++) {

            dp[i] = Math.min(dp[i - 1], dp[i - 2]) + cost[i];

        }

        return Math.min(dp[n - 2], dp[n - 1]);

    }

}

总结:

  在按照动规五部曲解题时,因为dp数组定义错误而导致无法正确解题。我将其错误定义为有i阶楼梯,dp[i]为爬上楼顶的最少花费体力,然后走了弯路,但其实可以发现,按照这个错误的定义是无法推出正确的结果的,如果发生这种情况就说明dp数组定义错误,我们需要重新定义。同时也说明了dp数组定义对解题的重要性。

  1)明确dp数组定义及下标含义:

    dp数组应正确定义为爬上第i阶楼梯花费的最少体力为dp[i]。

  2)推导递推公式:

    然后通过给定的第一个用例推dp[2],一共有2层台阶(从0开始)。

    根据所要求的值,我们倒着看,因为从一个台阶可以选择向上爬一个或两个台阶,所以要达到楼顶有两个选择:

    选择1:从第i阶台阶再爬1阶台阶到顶,花费体力dp[i];

    选择2:从第i-1阶台阶再爬2阶台阶到顶,花费体力dp[i-1]。

    所以到达第i级台阶的阶梯顶部的最小花费为minCost[i] = min(dp[i], dp[i-1])。

    那么接下来就是求爬上第i阶楼梯花费的最少体力 dp[i] 了。踏上第i级台阶有两种方法:

    方法一:先踏上第i-2级台阶(最小总花费dp[i-2]),再直接迈两步踏上第i级台阶(花费cost[i]),最小总花费dp[i-2] + cost[i];

    方法二:先踏上第i-1级台阶(最小总花费dp[i-1]),再迈一步踏上第i级台阶(花费cost[i]),最小总花费dp[i-1] + cost[i];

    则dp[i]是上面这两个最小总花费中的最小值。因此状态转移方程是:dp[i] = min(dp[i-2], dp[i-1]) + cost[i]

  3)初始化:

    因为dp[i]是由dp[i- 1]、dp[i-2]推出,所以我们只需初始化dp[0]、dp[1]即可。又因为我们可以从第0阶或第一阶开始爬台阶,所以初始化为:

dp[0] = cost[0]、

dp[1] = cost[1]

  4)确定遍历顺序:

    依然因为dp[i]是由dp[i- 1]、dp[i-2]推出,所以从前向后遍历即可。

  5)若代码不通过可打印数组进行debug,这里就省略了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值