【题目描述】
经过几个月辛勤的工作,FJ 决定让奶牛放假。假期可以在 1…N 天内任意选择一段(需要连续),每一天都有一个享受指数 W。但是奶牛的要求非常苛刻,假期不能短于 P 天,否则奶牛不能得到足够的休息;假期也不能超过 Q 天,否则奶牛会玩的腻烦。FJ 想知道奶牛们能获得的最大享受指数。
【输入】
第一行:N,P,Q. 第二行:N 个数字,中间用一个空格隔开。
【输出】
一个整数,奶牛们能获得的最大享受指数。
【样例输入】
5 2 4
-9 -4 -3 8 -6
【样例输出】
5
【样例解释】
选择第 3-4 天,享受指数为-3+8=5
【数据范围】
50% 1≤N≤10000
100% 1≤N≤100000
1<=p<=q<=n
=================题解================
前缀和 + dp + 单调队列。
写了树状数组。。。。但是树状数组求区间和比前缀和要慢啊。。。
首先前缀和,sum[i] = sum[i - 1] + sum[i – 2];所以对于区间[i,j],区间和sum(i,j) = sum[j] – sum[i],其中j – q <= i <= j – p;这时可以发现,若要sum(i,j)尽量大,那么=sum[i]要尽量小,这时要用单调递增队列维护i的区间,队列中存sum数组的下标。
单调队列满足两个性质:
1.单调队列必须满足从队头到队尾的严格单调性。
2.排在队列前面的比排在队列后面的要先进队。
元素进队列的过程对于单调递增队列,对于一个元素a 如果 a > 队尾元素,那么直接将a扔进队列;如果 a <= 队尾元素 则将队尾元素出队列,直到满足 a 大于队尾元素即可。
枚举j从p到n,即枚举右端点,对于每个枚举的右端点,更新单调队列,首先要保证head始终<= tail,当队尾元素的值sum[que[tail]] > 当前要进队的元素的值sum[j – p]时,队尾的标记tail要前移,tail--;之后队尾元素更新为j – p;对于队首,要保证q[head] > j – q,所以head要++,直到满足。这样更新完成后,队首元素的值就是最小的了,此时在ans与sum[j] – sum[q[head]]间取max。