设dp[i] 为 跳到当前这个点的最大值。
状态方程为 max{dp[i-k],…,dp[i-1]} + nums[j]. i-k >= 0;
表示当前这个点可以由这些点跳过来。
因为n和k都很大。故观察第二层,可以维护单调队列,维护区间长度为k的dp[i]的最大值。
每次只需要取出最大的dp[i] 去转移.
或者用mutilset来维护。
代码:
单调队列
class Solution {
public:
int maxResult(vector<int>& nums, int k) {
int n = (int)nums.size();
vector<int> dp(n+10,0);
dp[0] = nums[0];
deque<int> dq;
dq.push_back(0);
for(int i=1;i<n;i++){
while(dq.front() < i-k) dq.pop_front();
dp[i] = dp[dq.front()] + nums[i];
while(dq.size() && dp[dq.back()] <= dp[i]) dq.pop_back();
dq.push_back(i);
}
return dp[n-1];
}
};
multiset
class Solution {
public:
int maxResult(vector<int>& nums, int k) {
int n = (int)nums.size();
vector<int> dp(n);
dp[0] = nums[0];
multiset<int> st;
st.insert(dp[0]);
for(int i=1;i<n;i++){
if(i - k - 1>= 0) st.erase(st.find(dp[i-k-1]));
dp[i] = nums[i] + (*st.rbegin());
st.insert(dp[i]);
}
return dp[n-1];
}
};