【LeetCode刷题日志】:使用最小花费爬楼梯、整数拆分

114 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情

1、写在前面

大家好,这里是【LeetCode刷题日志】。今天的两道题分别是:

  • 使用最小花费爬楼梯
  • 整数拆分

2、内容

2.1、题目一:使用最小花费爬楼梯

链接:746. 使用最小花费爬楼梯 - 力扣(LeetCode)

(1) 描述

image.png

(2) 举例

image.png

(3) 解题

动态规划

  • dp[i-1] 跳到 dp[i] 需要花费 dp[i-1] + cost[i-1]
  • dp[i-2] 跳到 dp[i] 需要花费 dp[i-2] + cost[i-2]
  • 由于 dp[i] 表示到达第 i 台阶需花费的最少体力
  • 应该跳一步还是跳两步,取决于花费体力是否是最少的
  • 因此递推公式为:dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]);
class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int size = cost.size();
        vector<int> dp(size + 1);
        dp[0] = 0;
        dp[1] = 0;
        for(int i = 2; i <= size; i++) {
            dp[i] = min(dp[i-1] + cost[i-1], dp[i-2] + cost[i-2]);
        }
        return dp[size];
    }   
};

优化后:

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) {
        int pre = 0;
        int cur = 0;
        int next = 0;
        for (int i = 2; i <= cost.size(); i++) {
            next = min(cur + cost[i-1], pre + cost[i-2]);
            pre = cur;
            cur = next;
        }
        return cur;
    }
};

2.2、题目二:整数拆分

链接:343. 整数拆分 - 力扣(LeetCode)

(1) 描述

image.png

(2) 举例

image.png

(3) 解题

动态规划

// dp[i]:  表示数字 i 被分拆后,可以得到的最大乘积值
// 递推公式: dp[i] = max( dp[i],  max( (i-j) * j, dp[i-j] * j) );
class Solution {
public:
    int integerBreak(int n) {
        vector<int> dp(n + 1);
        // 由于拆分数字 0 或 拆分数字 1 都是没有意义的,因此从数字 2 开始拆分
        // 数字 2 拆分后最大乘积为 1
        dp[2] = 1;
        // i 从 3 开始枚举
        for (int i = 3; i <= n ; i++) {
            // j 从 1 开始枚举
            for (int j = 1; j < i - 1; j++) {
                dp[i] = max(dp[i], max((i - j) * j, dp[i - j] * j));
            }
        }
        // 返回结果
        return dp[n];
    }
};

数学法

将给定的正整数拆分成尽可能多的 3,并对余数进行分类讨论,则最后相乘得到的值将达到最大。

具体数学证明可参考官网。

class Solution {
public:
    int integerBreak(int n) {
        if(n == 2) return 1;
        if(n == 3) return 2;
        int q = n / 3;
        int y = n % 3;
        if(y == 0) {
            return (int)pow(3, q);
        }
        else if(y == 1) {
            return (int)pow(3, q-1) * 4;
        }
        else {
            return (int)pow(3, q) * 2;
        }
    }
};

3、写在最后

好的,今天就先刷到这里。