最先能到达的是l位置,对于每一个新遍历到的位置,我们向单调队列加入dp[i-l],在对head进行范围约束,这样我们就得到了在[i-r,i-l]范围内的最大值,更新dp[i]即可
最后输出的时候需要再可能到达n的区间
#include <iostream>
# include<algorithm>
using namespace std;
typedef long long int ll;
int dp[200000+10];
int q1[200000+10],q2[200000+10];
int a[200000+10];
int main()
{
int n,l,r;
cin>>n>>l>>r;
for(int i=0;i<=n;i++)
{
cin>>a[i];
}
dp[0]=0;
fill(dp,dp+200000+10,-9999999);
dp[0]=0;
int head=0,tail=0;
for(int i=l;i<=n;i++)
{
while(head<tail&&dp[i-l]>=q2[tail-1])
tail--;
q2[tail]=dp[i-l];
q1[tail]=i-l;
tail++;
while(head<tail&&q1[head]+r<i)
head++;
dp[i]=q2[head]+a[i];
}
int ans=-9999999;
for(int i=n-r+1;i<=n;i++)
{
ans=max(ans,dp[i]);
}
cout<<ans;
return 0;
}