Leetcode2786. 访问数组中的位置使分数最大

Every day a Leetcode

题目来源:2786. 访问数组中的位置使分数最大

解法1:动态规划

状态数组:

  • dp[i][0]: 访问下标范围 [0, i] 中的元素且最后访问的元素是偶数时的最大得分;
  • dp[i][1]: 访问下标范围 [0, i] 中的元素且最后访问的元素是奇数时的最大得分。

初始化:

  1. 如果 nums[0] 是奇数:dp[0][0] = INT_MIN,dp[0][1] = nums[0];
  2. 如果 nums[0] 是偶数:dp[0][0] = nums[0],dp[0][1] = INT_MIN。

状态转移:

  1. 如果 nums[i] 是奇数:
    • dp[i][0] = dp[i - 1][0]
    • dp[i][1] = max(dp[i - 1][0] - x, dp[i - 1][1]) + nums[i]
  2. 如果 nums[i] 是偶数:
    • dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - x) + nums[i]
    • dp[i][1] = dp[i - 1][1]

答案:max(dp[n - 1][0], dp[n - 1][1])。

代码:

/*
 * @lc app=leetcode.cn id=2786 lang=cpp
 *
 * [2786] 访问数组中的位置使分数最大
 */

// @lc code=start
class Solution
{
   
public:
    long long maxScore(vector<int> &nums, int x)
    {
   
        // 特判
        if (nums.empty())
            return 0;
        if (x == 0)
            return accumulate(nums.begin(), nums.end(), 0LL);

        int n = nums.size();
        // 状态数组
        // dp[i][0]: 访问下标范围 [0, i] 中的元素且最后访问的元素是偶数时的最大得分
        // dp[i][1]: 访问下标范围 [0, i] 中的元素且最后访问的元素是奇数时的最大得分
        vector<vector<long long>> dp(n, vector<long long>(2, 0));
        // 初始化
        if (nums[0] % 2)
        {
   
            dp[0][0] = INT_MIN;
            dp[0][1] = nums[0];
        }
        else
        {
   
            dp[0][0] = nums[0];
            dp[0][1] = INT_MIN;
        }
        // 状态转移
        for (int i = 1; i < n; i++)
        {
   
            if (nums[i] % 2)
            {
   
                dp[i][0] = dp[i - 1][0];
                dp[i][1] = max(dp[i - 1][0] - x, dp[i - 1][1]) + nums[i];
            }
            else
            {
   
                dp[i][0] = max(dp[i - 1][0], dp[i - 1][1] - x) + nums[i];
                dp[i][1] = dp[i - 1][1];
            }
        }
        return max(dp[n - 1][0], dp[n - 1][1]);
    }
};
// @lc code=end

结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(n),其中 n 是数组 nums 的长度。

空间复杂度:O(n),其中 n 是数组 nums 的长度。

解法2:动态规划 - 空间优化

我们发现,dp[i][0] 和 dp[i][1] 只取决于它们前面的两个值:dp[i - 1][0] 和 dp[i - 1][1],因此可以可以优化。

代码:

// 动态规划 - 空间优化

class Solution
{
   
public:
    long long maxScore(vector<int> &nums, int x)
    {
   
        // 特判
        if (nums.empty())
            return 0LL;
        if (x == 0)
            return accumulate(nums.begin(), nums.end(), 0LL);

        int n = nums.size();
        long long odd = nums[0] % 2 ? nums[0] : INT_MIN;  // 奇数
        long long even = nums[0] % 2 ? INT_MIN : nums[0]; // 偶数
        // 状态转移
        for (int i = 1; i < n; i++)
        {
   
            if (nums[i] % 2)
                odd = max(odd, even - x) + nums[i];
            else
                even = max(odd - x, even) + nums[i];
        }
        return max(odd, even);
    }
};

结果:

在这里插入图片描述

复杂度分析:

时间复杂度:O(n),其中 n 是数组 nums 的长度。

空间复杂度:O(1)。

最近更新

  1. TCP协议是安全的吗?

    2024-02-10 16:20:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-02-10 16:20:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-02-10 16:20:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-02-10 16:20:02       18 阅读

热门阅读

  1. MinGW/MSYS/GCC/GNU/MSVC/Clang/LLVM都是什么

    2024-02-10 16:20:02       21 阅读
  2. Python基础篇_修饰符(Decorators)【下】

    2024-02-10 16:20:02       27 阅读
  3. c#通过反射完成对象自动映射

    2024-02-10 16:20:02       22 阅读
  4. 2.8作业

    2024-02-10 16:20:02       26 阅读
  5. 11.3 OpenGL可编程顶点处理:几何着色器

    2024-02-10 16:20:02       33 阅读
  6. 前端代码整洁规范之道

    2024-02-10 16:20:02       29 阅读