Bootstrap

Leetcode3196. 最大化子数组的总成本

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 的长度。

;