前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Min Cost Climbing Stairs

Min Cost Climbing Stairs

作者头像
卡尔曼和玻尔兹曼谁曼
发布2019-01-22 09:28:38
4980
发布2019-01-22 09:28:38
举报
文章被收录于专栏:给永远比拿愉快

Min Cost Climbing Stairs

题目

On a staircase, the i-th step has some non-negative cost cost[i] assigned (0 indexed).

Once you pay the cost, you can either climb one or two steps. You need to find minimum cost to reach the top of the floor, and you can either start from the step with index 0, or the step with index 1.

Example 1:

代码语言:javascript
复制
Input: cost = [10, 15, 20]
Output: 15
Explanation: Cheapest is start on cost[1], pay that cost and go to the top.

Example 2:

代码语言:javascript
复制
Input: cost = [1, 100, 1, 1, 1, 100, 1, 1, 100, 1]
Output: 6
Explanation: Cheapest is start on cost[0], and only step on 1s, skipping cost[3].

思路分析

其实,刚看到这个题目的时候,我是有点迷惑的,甚至浪费了不少时间。

比如对于第一个例子,我以为结果应该是10。因为我从第0个台阶开始,跨两步就可以到达最顶层。

然而,这样的理解和题目的本意是不相符的。题目中的“top of the floor”只的是最后一层台阶的更上一层。也就是说,对于第一个例子,我需要跨到3层(从0开始)台阶上去。如果从第0个台阶开始的话,花费是(10+20)= 30,而如果从第1个台阶开始,直接跨两步的话,则花费是15。

理解了题目含义,我们开始做题。很显然,这是一道动态规划问题。

而且我们有如下递归公式:

⎧⎩⎨⎪⎪dp[0]=cost[0]dp[1]=cost[1]dp[i]=cost[i]+min(dp[i−1],dp[i−2]){dp[0]=cost[0]dp[1]=cost[1]dp[i]=cost[i]+min(dp[i−1],dp[i−2])

\left\{ \begin{array}{**lr**} \mathrm{dp}[0] = \mathrm{cost}[0] & \\ \mathrm{dp}[1] = \mathrm{cost}[1] & \\ \mathrm{dp}[i] = \mathrm{cost}[i] + \mathrm{min}(\mathrm{dp}[i-1], \mathrm{dp}[i-2]) & \end{array} \right.

从第2层开始,我们往上走的选择是保持当前的花费最小,从而我们从前面的花费中选择最小的和当前的楼层的cost[i]cost[i]\mathrm{cost}[i]相加。最后的返回值应该是min(dp[i],dp[i−1])min(dp[i],dp[i−1])\mathrm{min}(\mathrm{dp}[i], \mathrm{dp}[i-1])。这种思路是一种正向思考。

这是一种思路,其实我们还有另外一种思路。

⎧⎩⎨⎪⎪dp[0]=0dp[1]=0dp[i]=min(cost[i−1]+dp[i−1],cost[i−2]+dp[i−2]){dp[0]=0dp[1]=0dp[i]=min(cost[i−1]+dp[i−1],cost[i−2]+dp[i−2])

\left\{ \begin{array}{**lr**} \mathrm{dp}[0] = 0 & \\ \mathrm{dp}[1] = 0 & \\ \mathrm{dp}[i] = \mathrm{min}(\mathrm{cost}[i - 1] + \mathrm{dp}[i-1], \mathrm{cost}[i - 2] + \mathrm{dp}[i-2]) & \end{array} \right. 因为从2开始,第iii层的花费可以由通过i−2i−2i-2层走2层或者通过i−1i−1i-1走1层到达,而i−2i−2i-2和i−1i−1i-1层所要花费的值分别为cost[i−2i−2i-2]和cost[i−1i−1i-1]。最后的返回值应该是dp[i]dp[i]\mathrm{dp}[i]。这种思路是一种反向思考,假设我们已经到达了顶点,然后列出我们达到顶点之前的两种可能选择。

C++实现

代码语言:javascript
复制
#include <iostream>
#include <vector>
#include <cmath>

using namespace std;

int minCostClimbingStairs(vector<int> &cost) {
    // 第二种思路
    int dp0 = 0;
    int dp1 = 0;
    int dp = 0;
    for (int i = 2; i <= cost.size(); i++) {
        dp = min(dp0 + cost[i - 2], dp1 + cost[i -1]);
        dp0 = dp1;
        dp1 = dp;
    }
    return dp;
    /* 第一种思路
    int dp0 = cost[0];
    int dp1 = cost[1];
    int dp = 0;
    for (int i = 2; i < cost.size(); i++) {
        dp = cost[i] +  min(dp0, dp1);
        dp0 = dp1;
        dp1 = dp;
    }
    return min(dp0, dp1);
    */
}

int main() {
    unsigned int n = 0;
    cout << "请输入楼梯层数:\n";
    cin >> n;
    vector<int> cost(n);
    cout << "请输入每层的权值:\n";
    for (int i = 0; i < n; i++) {
        cin >> cost[i];
    }
    int result = minCostClimbingStairs(cost);
    cout << result << endl;
    return 0;
}

Scala实现

代码语言:javascript
复制
package leetcode

import scala.math._
import scala.io.StdIn

object MinCostClimbingStairs {
  def minCostClimbingStairs(cost: Array[Int]): Int = {
    val dp = cost.clone
    for (i <- 2 until cost.length) {
      dp(i) = cost(i) + min(dp(i - 1), dp(i -2))
    }
    return min(dp(dp.length - 1), dp(dp.length - 2))
  }

  def main(args: Array[String]): Unit = {
    println("请输入楼梯层数:")
    val count = StdIn.readInt()
    val cost = Array.fill[Int](count)(0)
    println("请输入每层的权值:")
    for (i <- 0 until cost.length) {
      cost(i) = StdIn.readInt()
    }

    println(minCostClimbingStairs(cost))
  }

}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018年09月04日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Min Cost Climbing Stairs
    • 题目
      • 思路分析
        • C++实现
          • Scala实现
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档