P1725 琪露诺
题目描述:
n+1个格子,从0开始,从当前位置可以跳到[i+l,i+r]位置,每个位置有冰冻指数,问达到n之后的位置可以得到最大的冰冻指数是多少
思路:
写过类似的题,考虑用dp,设j属于区间[i-r,i-l] dp[i]=max(a[i]+dp[j],dp[i]),但题目数据过大n*(r-l)有t的可能,然后发现这个递推式其实就是在[i-l,i-r]区间内找到一个最大的值,这个可以使用单调队列维护
#include<bits/stdc++.h>
using namespace std;
#define int long long
int dp[200005];
signed main(){
int n,l,r;
deque<pair<int,int> > q;
scanf("%lld %lld %lld",&n,&l,&r);
int a,ans=-1e9-5;
dp[0]=0;
scanf("%lld",&a);
q.push_back(pair<int,int> (0,0));
for(int i=1;i<=n;i++){
scanf("%lld",&a);
if(i<l){
dp[i]=-1e9-5;
}
if(i>=l){
if(!q.empty()&&q.front().first<i-r)q.pop_front();
while(!q.empty()&&dp[i-l]>=q.back().second){
q.pop_back();
}
q.push_back(pair<int,int>(i-l,dp[i-l]));
dp[i]=q.front().second+a;
}
}
for(int i=n-r+1;i<=n;i++){
ans=max(ans,dp[i]);
}
printf("%lld",ans);
return 0;
}