题解 P1725 【琪露诺】
費了九牛二虎之力終於a掉了這題。。。
首先我們要找到dp方程:
F[i]=max{f[k]}+a[i] , i-r<=k<=i-l, k>=0
千萬記住左邊是i-r,右邊是i-l!!!
我爲了這個wa了無數次。。。
由於只和f[k]的值以及編號有關,我們可以用單調隊列維護。
stl大法好!! (不過不太建議noip選手使用。。。 我是因爲不會手寫才勉强用stl的)
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<map>
#include<vector>
#include<cstring>
#include<cmath>
#include<queue>
using namespace std;
int n,l,r,ans=-2000000000;
int f[200001*2],a[200010*2];
struct mmm{int v,num;};
deque <mmm> q;
mmm x;
int fastRead()
{
int f=1,re=0;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9'){re=re*10+c-'0';c=getchar();}
return f*re;
}
int main()
{
n=fastRead(),l=fastRead(),r=fastRead();
for(int i=0;i<=n;i++)
{
a[i]=fastRead();
}
memset(f,128,sizeof(f));
f[0]=0;x.num=0;x.v=0;q.push_back(x);
for(int i=l;i<=n+r;i++)
{
while(!q.empty()&&q.front().num<(i-r))q.pop_front();
if(f[i-l]>-2000000)
{
x.v=f[i-l];x.num=i-l;
while(!q.empty()&&q.back().v<=x.v)q.pop_back();
q.push_back(x);
}
if(!q.empty())f[i]=q.front().v+a[i];
}
for(int i=n+1;i<=n+r;i++)
ans=max(ans,f[i]);
printf("%d",ans);
return 0;
}