Every day a Leetcode
题目来源:3196. 最大化子数组的总成本
解法1:记忆化搜索
因为要解决的问题都形如「a[0] 到 a[i] 的最大成本和」,所以用它作为本题的状态定义 dfs(i)。
分类讨论:
- 分成长为 1 的子数组,即 a[i] 单独作为一个长为 1 的子数组,接下来需要解决的问题为:a[0] 到 a[i−1] 的最大成本和,即 dfs(i)=dfs(i−1)+a[i]。
- 分成长为 2 的子数组,即 a[i−1] 和 a[i] 作为一个长为 2 的子数组,接下来需要解决的问题为:a[0] 到 a[i−2] 的最大成本和,即 dfs(i)=dfs(i−2)+a[i−1]−a[i]。
这两种情况取最大值,就得到了 dfs(i),即:dfs(i)=max(dfs(i−1)+a[i],dfs(i−2)+a[i−1]−a[i])。
递归边界:dfs(−1)=0,dfs(0)=a[0]。
递归入口:dfs(n−1),也就是答案。
代码:
#
# @lc app=leetcode.cn id=3196 lang=python3
#
# [3196] 最大化子数组的总成本
#
# @lc code=start
class Solution:
def maximumTotalCost(self, nums: List[int]) -> int:
@cache
def dfs(i: int) -> int:
if i < 0:
return 0
if i == 0:
return nums[0]
return max(dfs(i - 1) + nums[i], dfs(i - 2) + nums[i - 1] - nums[i])
return dfs(len(nums) - 1)
# @lc code=end
结果:
复杂度分析:
时间复杂度:O(n),其中 n 是数组 nums 的长度。
空间复杂度:O(n),其中 n 是数组 nums 的长度。
解法2:
代码:
/*
* @lc app=leetcode.cn id=3196 lang=cpp
*
* [3196] 最大化子数组的总成本
*/
// @lc code=start
class Solution
{
public:
long long maximumTotalCost(vector<int> &nums)
{
int n = nums.size();
vector<long long> dp(n + 1);
// 初始化
dp[0] = 0;
dp[1] = nums[0];
// 动态规划
for (int i = 2; i <= n; i++)
dp[i] = max(dp[i - 1] + nums[i - 1], dp[i - 2] + nums[i - 2] - nums[i - 1]);
return dp[n];
}
};
// @lc code=end
结果:
复杂度分析:
时间复杂度:O(n),其中 n 是数组 nums 的长度。
空间复杂度:O(n),其中 n 是数组 nums 的长度。