https://www.luogu.org/problemnew/show/P1725
题意中文的不说了;
做法:首先可以想到一个dp方程 dp[i]表示当前位置i的最大值,dp[i]=max(dp[j])+a[i] j表示可以跳到i的位置,但不过暴力肯定T了
但不过仔细一想,能到i的位置的区间长度是固定的,所以直接用单调栈维护,在i前面的(i-l,i-r)的区间就可以了,注意,长度不足的情况
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=2e5+10;
int n,l,r,a[N],dp[N];
int que[N],head,tail,id[N];
int main()
{
scanf("%d%d%d",&n,&l,&r);
for(int i=1;i<n;i++) scanf("%d",&a[i]);
memset(dp,0,sizeof(dp));
dp[1]=a[1];
head=1,tail=0;
for(int i=l+1;i<=n;i++)
{
while(head<=tail&&que[tail]<=dp[i-l]) tail--;
que[++tail]=dp[i-l],id[tail]=i-l;
while(id[head]<i-r+1) head++;
dp[i]=max(dp[i],que[head]+a[i]);
}
int ans=0;
for(int i=n-r+1;i<=n;i++)
ans=max(dp[i],ans);
printf("%d\n",ans);
return 0;
}