SSL_2884【假期】

假期

题目

经过几个月辛勤的工作,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;
}

猜你喜欢

转载自blog.csdn.net/zhanglili1597895/article/details/114407004