开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第15天,点击查看活动详情
1、写在前面
大家好,这里是【LeetCode刷题日志】。今天的两道题分别是:
- 使用最小花费爬楼梯
- 整数拆分
2、内容
2.1、题目一:使用最小花费爬楼梯
链接:746. 使用最小花费爬楼梯 - 力扣(LeetCode)
(1) 描述
(2) 举例
(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、题目二:整数拆分
(1) 描述
(2) 举例
(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、写在最后
好的,今天就先刷到这里。