使用动态规划,dp[i]表示以i结束的最大子序列和,每个以i位置结束的有k+1个选择,子序列只有这个元素或者从前面k个位置的某一个位置接上。
然后快速求前面k个的最大值,可以用到堆,从旧到新、从大到小队列
struct Node{
int pos;
int val;
};
bool operator<(const Node &a,const Node &b){
return a.val<b.val;
}
class Solution {
public:
int constrainedSubsetSum(vector<int>& nums, int k) {
int n=nums.size();
vector<int> dp(n,0);
priority_queue<Node> q;
for(int i=0;i<n;i++){
dp[i]=nums[i];
while(!q.empty() &&q.top().pos<i-k){
q.pop();
}
if(!q.empty()){
dp[i]=max(dp[i],nums[i]+q.top().val);
}
Node node;
node.pos=i;
node.val=dp[i];
q.push(node);
}
int ans=nums[0];
for(int i=0;i<n;i++){
ans=max(ans,dp[i]);
}
return ans;
}
};
struct Node{
int pos;
int val;
};
class Solution {
public:
int constrainedSubsetSum(vector<int>& nums, int k) {
int n=nums.size();
vector<int> dp(n,0);
deque<Node> q;
for(int i=0;i<n;i++){
dp[i]=nums[i];
while(!q.empty() && q.front().pos<i-k){
q.pop_front();
}
if(!q.empty()){
dp[i]=max(dp[i],nums[i]+q.front().val);
}
Node node;
node.pos=i;
node.val=dp[i];
while(!q.empty() && q.back().val<=node.val){
q.pop_back();
}
q.push_back(node);
}
int ans=nums[0];
for(int i=0;i<n;i++){
ans=max(ans,dp[i]);
}
return ans;
}
};
本文介绍了解决LeetCode上受限子序列和问题的一种高效算法。通过动态规划方法,结合优先队列或双端队列,快速找到满足条件的最大子序列和。详细解析了算法的实现过程和代码细节。
413

被折叠的 条评论
为什么被折叠?



