代码随想录算法训练营第三十八天|LeetCode509 斐波那契数、LeetCode70 爬楼梯、LeetCode746 使用最小花费爬楼梯

题1:

指路:509. 斐波那契数 - 力扣(LeetCode)
思路与代码:
1.基础思路:

动态规划入门题。动态规划类的题目我们分为五步走。首先,确定动规数组的含义,一般将数组称为dp,本题中显而易见含义是斐波那契数;其次,确定递推公式,本题中题意中指出很明确,是为“后面每一项数字都是前面两项数字的和”,也就是F(n) = F(n - 1) + F(n - 2);然后,完成dp数组的初始化,同样本题中题意很明确,由0和1开始,即F(0) = 0, F(1) = 1;接着,确定dp数组的遍历顺序,由上一条我们可以知道后面的数字由前两项确定,因此我们选择从前向后遍历;最后,打印dp数组,本题中未见得陷阱,直接将dp数组返回即可。代码如下:

class Solution {
public:
    int fib(int n) {
    if (n <= 1) return n;
    // 确定dp数组
    vector<int> dp(n+1);
    // 初始化dp数组
    dp[0] = 0; dp[1] = 1;
    // 从前向后遍历
    for (int i = 2; i <= n; i++) {
    // 放入递推公式
        dp[i] = dp[i - 1] + dp[i - 2];
    }
    // 打印数组
     return dp[n];
    }
};
2.压缩操作:

对于这个题,我们知道“后面每一项数字都是前面两项数字的和”,即本项仅与前两项的和有关,我们只需要维护前两项即可。代码入下:

class Solution {
public:
    int fib(int n) {
    if (n <= 1) return n;
    // 定义dp数组
    int dp[2];
    // 初始化dp数组
    dp[0] = 0; dp[1] = 1;
    // 确定遍历顺序
    for (int i = 2; i <= n; i++) {
    // 递推公式
        int sum = dp[0] + dp[1];
        dp[0] = dp[1];
        dp[1] = sum;
    }
    // 打印数组
    return dp[1];
    }
};

题2:

指路:70. 爬楼梯 - 力扣(LeetCode)
思路与代码:

对于这个题需要列出前几步找规律。当目的地在地面上时我们不需要走就可以到顶,当目的地在第一阶时走一步即可只有一种情况;当目的地在第二阶时可以一次走一步走两次也可以一次走两步走一次,也就是两种情况;同样在第三阶时,可以一次走一步走三次,先走一步再走两步或者先走两步再走一步共三种情况;相似得出,目的地在第四阶有五种情况。由此我们得出,本阶梯的到达种数为前两阶种数的和。现在开始按照顺序解题。首先,定义dp数组,我们将其设置为阶梯到达的种数;其次,找到递推公式,我们在前面已经找到了规律,即本阶梯的到达种数为前两阶种数的和;然后,我们对数组进行初始化,前面也有提到,即dp[0]=0,dp[1]=1,dp[2]=2;接着我们确定遍历顺序,因为本阶梯的数量由前两项确定,因此遍历顺序为从前往后;最后输出即可。在这里我们直接将压缩操作,类似于上一题,仅仅维护前两项的和即可。代码如下:

class Solution {
public:
    int climbStairs(int n) {
    if (n == 0) return 0;
    if (n == 1) return 1;
    // 确定dp数组
    int dp[3];
    // 初始化
    dp[0] = 0;
    dp[1] = 1; dp[2] = 2;
    // 确定遍历顺序
    for (int i = 3; i <= n; i++) {
    // 确定递推公式    
        int sum = dp[1] + dp[2];
        dp[1] = dp[2];
        dp[2] = sum;
    }
    // 返回数组
    return dp[2];
    }
};

题3:

指路:746. 使用最小花费爬楼梯 - 力扣(LeetCode)
思路与代码:

本题有两个地方需要明确:第一是关于体力值的花费,数组cost[i]的值是当从台阶i往上跳的时候才花费对应的体力;第二是关于楼顶,是cost数组最后一个花费体力值花费掉之后才到达楼顶,也就是cost.size() + 1。首先,定义dp数组,我们将其设置为到达i位置所需要的最小花费;其次,找到递推公式,本题中为到达前一步所需体力值加上前一步到本步的体力值到达前两步所需体力值到本步体力值中二者取较小值;然后,我们对数组进行初始化,可以选择从0或1阶开始,我们到达0台阶需要花费0,同样到达台阶1花费也是0,即dp[0]=0,dp[1]=0;接着我们确定遍历顺序,因为本阶梯的数量由前两布确定,因此遍历顺序为从前往后;最后输出即可。在这里我们直接将压缩操作,仅仅维护前两项即可。代码如下:

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
    // 初始化
    int dp0 = 0; int dp1 = 0;
    for (int i = 2; i <= cost.size(); i++) {
        int dpi = min(dp1 + cost[i - 1], dp0 + cost[i - 2]);
        dp0 = dp1;
        dp1 = dpi;
    }
    return dp1;
    }
};

  • 15
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

C.G.道枝

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

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

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

打赏作者

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

抵扣说明:

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

余额充值