假期
题目
经过几个月辛勤的工作,FJ决定让奶牛放假。假期可以在1…N天内任意选择一段(需要连续),每一天都有一个享受指数W。但是奶牛的要求非常苛刻,假期不能短于P天,否则奶牛不能得到足够的休息;假期也不能超过Q天,否则奶牛会玩的腻烦。FJ想知道奶牛们能获得的最大享受指数。
Input
第一行:N,P,Q.
第二行:N个数字,中间用一个空格隔开,每个数都在longint范围内。
Output
一个整数,奶牛们能获得的最大享受指数。
Sample Input
5 2 4
-9 -4 -3 8 -6
Sample Output
5
数据范围
p<=q<=n<=106
解析
裸的单调队列优化DP,先前缀和,每轮循环踢掉>=a[i-p]的队尾,加入i-p,踢出<i-q的队头,求最大值即可
code:
#include<cstdio>
#include<deque>
#define int long long
using namespace std;
inline int max(int x,int y){return (x>y)?x:y;}
inline bool idigit(char x){return (x<'0'|x>'9')?0:1;}
inline int read()
{
int num=0,f=1;
char c=0;
while(!idigit(c=getchar())){if(c=='-')f=-1;}
while(idigit(c))num=(num<<1)+(num<<3)+(c&15),c=getchar();
return num*f;
}
inline void write(int x)
{
int F[20];
int tmp=x>0?x:-x;
if(x<0)putchar('-');
int cnt=0;
while(tmp>0){F[cnt++]=tmp%10+'0';tmp/=10;}
while(cnt>0)putchar(F[--cnt]);
if(x==0)putchar('0');
}
int n,p,q,a[100010],maxn=-1e18;
deque <int> b;
signed main()
{
n=read(),p=read(),q=read();
for(int i=1;i<=n;i++)a[i]=read()+a[i-1];
for(int i=p;i<=n;i++)
{
while(!b.empty()&&a[b.back()]>=a[i-p])b.pop_back();
b.push_back(i-p);
while(!b.empty()&&b.front()<i-q)b.pop_front();
maxn=max(maxn,a[i]-a[b.front()]);
}
write(maxn);
return 0;
}