Leetcode 1425: DP + 单调队列

  1. Constrained Subsequence Sum
    Hard

Given an integer array nums and an integer k, return the maximum sum of a non-empty subsequence of that array such that for every two consecutive integers in the subsequence, nums[i] and nums[j], where i < j, the condition j - i <= k is satisfied.

A subsequence of an array is obtained by deleting some number of elements (can be zero) from the array, leaving the remaining elements in their original order.

Example 1:

Input: nums = [10,2,-10,5,20], k = 2

Output: 37

Explanation: The subsequence is [10, 2, 5, 20].

Example 2:

Input: nums = [-1,-2,-3], k = 1

Output: -1

Explanation: The subsequence must be non-empty, so we choose the largest number.

Example 3:

Input: nums = [10,-2,-10,-5,20], k = 2

Output: 23

Explanation: The subsequence is [10, -2, -5, 20].

Constraints:

1 <= k <= nums.length <= 105

-104 <= nums[i] <= 104

解法1:DP。会超时。

cpp 复制代码
class Solution {
public:
    int constrainedSubsetSum(vector<int>& nums, int k) {
        int n = nums.size();
        vector<int> dp(n, INT_MIN / 3);
        dp[0] = nums[0];
        int res = dp[0];
        for (int i = 1; i < n; i++) {
            dp[i] = nums[i];
            for (int j = 1; j <= k; j++) {
                
                if (i >= j) {
                    dp[i] = max(dp[i], dp[i - j] + nums[i]);
                }       
            }
            res = max(res, dp[i]);
        }
       
        return res;
    }
};

解法2:DP+单调队列。注意单调队列本身就是一个滑动窗口。

cpp 复制代码
class Solution {
public:
    int constrainedSubsetSum(vector<int>& nums, int k) {
        int n = nums.size();
        vector<int> dp(n, INT_MIN / 3);
        dp[0] = nums[0];
        int res = dp[0];
        deque<int> dq;
        dq.push_back(0);
        for (int i = 1; i < n; i++) {
            while (!dq.empty() && i - dq.front() > k) dq.pop_front(); 
            dp[i] = max(nums[i], dp[dq.front()] + nums[i]);
            while (!dq.empty() && dp[dq.back()] < dp[i]) dq.pop_back();
            dq.push_back(i);
            res = max(res, dp[i]);
        }
        return res;
    }
};
相关推荐
li星野几秒前
[特殊字符] 模拟试卷一:C++核心与系统基础(90分钟)答案版
开发语言·c++·算法
二进制星轨14 分钟前
leecode-283-移动零-算法题解
算法
老鼠只爱大米22 分钟前
LeetCode经典算法面试题 #215:数组中的第K个最大元素(快速选择、堆排序、计数排序等多种实现方案详解)
算法·leetcode·堆排序·快速选择·topk·数组中的第k个最大元素
2301_8166512228 分钟前
C++中的享元模式变体
开发语言·c++·算法
逆境不可逃31 分钟前
LeetCode 热题 100 之 35. 搜索插入位置 74. 搜索二维矩阵 34. 在排序数组中查找元素的第一个和最后一个位置
数据结构·算法·leetcode
m0_5832031332 分钟前
C++中的访问者模式变体
开发语言·c++·算法
浅念-38 分钟前
C ++ 智能指针
c语言·开发语言·数据结构·c++·经验分享·笔记·算法
不染尘.39 分钟前
最小生成树算法
开发语言·数据结构·c++·算法·图论
Klong.k1 小时前
判断是不是素数题目
数据结构·算法
QQsuccess1 小时前
AI全体系保姆级详讲——第一部分:了解AI基本定义
人工智能·算法