放假

来源:互联网 发布:单片机的最小系统 编辑:程序博客网 时间:2024/06/07 22:32

放假

题目描述

经过几个月辛勤的工作,FJ决定让奶牛放假。假期可以在1…N天内任意选择一段(需要连续),每一天都有一个享受指数W。但是奶牛的要求非常苛刻,假期不能短于P天,否则奶牛不能得到足够的休息;假期也不能超过Q天,否则奶牛会玩的腻烦。FJ想知道奶牛们能获得的最大享受指数。

输入格式 1762.in

第一行:N,P,Q.
第二行:N个数字,中间用一个空格隔开。

输出格式 1762.out

一个整数,奶牛们能获得的最大享受指数。

输入样例 1762.in

5 2 4
-9 -4 -3 8 -6 

输出样例 1762.out

5
Limitation
50% 1≤N≤10000
100% 1≤N≤100000
1 <= p <= q <= n
Hint
选择第3-4天,享受指数为-3+8=5。 


    先从暴力方法入手。如果暴力做,那就枚举右端点,在sum[i-q],sum[i-q+1]……sum[i-p]中取一个MIN,用sum[i]减去它更新答案。取 MIN 可以用线段树做,也可以用单调队列。单调队列更快,且代码更短。

   于是,维护一个单调递减序列,套模板。不过值得注意的是,由于不能短于p天,因此,运行到i的时候,才尝试将sum[i-p]入队;由于不能多于q天,因此每次都要将下标小于i-q的出队。队首元素即为所求的MIN值。

    时间复杂度:O(N)

        代码如下:

#include#includeusing namespace std;const int MAXN=100005;int p,qq,n;long long a[MAXN],f[MAXN];long long s,ans,head=1,tail=0;long long q[MAXN],in[MAXN],sum[MAXN];int main(){ios::sync_with_stdio(false);cin>>n>>p>>qq;for(int i=1;i<=n;i++){cin>>a[i];sum[i]=sum[i-1]+a[i];}ans=100000000000000;ans=-ans;for(int i=p;i<=n;i++){while(head<=tail&&sum[q[tail]]>=sum[i-p])tail--;q[++tail]=i-p;while(head<=tail&&q[head]<(i-qq))head++;ans=max(ans,sum[i]-sum[q[head]]);}cout<

原创粉丝点击