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

在这里插入图片描述
这道题的意思是说,你站在一个台阶上,需要支付相应的费用才可以继续向上走

定义一个dp数组,dp[i]表示站在第i层台阶已经支付的费用,由于我们直接就能站到0和1级台阶,不需要支付费用,因此 dp[0]=0,dp[1]=0

状态转移方程为:dp[i] = min(dp[i-2] + cost[i-2], dp[i-1] + cost[i-1])

要想到达 i 级台阶,则必须指向i-2或i-1级台阶的费用,加上先前的费用dp[i-2]/dp[i-1]

最后需要返回dp[n],因为n-1表示最后一级台阶,dp[n-1]表示站在n-1级台阶已经花费的费用

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        // dp[i]:站在第i层台阶已经支付的费用
        // 最后需要返回dp[n],因为dp[n-1]表示最后一级台阶
        int n = cost.size();
        int* dp = new int[n+1];
        dp[0] = 0;
        dp[1] = 0;
        for(int i = 2; i <= n; i++){
            dp[i] = min(dp[i-2] + cost[i-2], dp[i-1] + cost[i-1]);
        }
        return dp[n];
    }
};

进阶:打印经过的路径

我们定义一个记录路径的数组path,path[i]表示站在 i 级台阶时,是从path[i] 级台阶上来的。我们最后一步是从path[n]出发的,所以path数组长度的应该是n+1,将0和1级台阶的path记为-1,表示起点

每次更新dp数组的时候,同时更新path数组,记录到当前台阶是从哪个台阶过来的

比如对于如下的cost数组来说,path数组应该为如下形式:

在这里插入图片描述
我们回溯时,先把路径记录在stack中,然后再输出就是路径了

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        // dp[i]:站在第i层台阶已经支付的费用
        // 最后需要返回dp[n],因为dp[n-1]表示最后一级台阶
        int n = cost.size();
        int* dp = new int[n+1];
        int* path = new int[n+1];
        path[0] = path[1] = -1;

        dp[0] = 0;
        dp[1] = 0;
        for(int i = 2; i <= n; i++){
            dp[i] = min(dp[i-2] + cost[i-2], dp[i-1] + cost[i-1]);
            if(dp[i] == dp[i-2] + cost[i-2]){
                // 从i-2级台阶爬上来
                path[i] = i - 2;
            }else{
                // 从i-1级台阶爬上来
                path[i] = i - 1;
            }
        }

        stack<int> st;
        int p = path[n]; // 最后一步从path[n]出发的,越过第n级台阶,到达终点
        while(p != -1){
            st.push(p);
            p = path[p];
        }
        while(!st.empty()){
            cout << st.top() << " ";
            st.pop();
        }
        return dp[n];
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

bugcoder-9905

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

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

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

打赏作者

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

抵扣说明:

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

余额充值