正题
题目链接:http://www.joyoi.cn/problem/tyvj-1305
题目大意
求一段长度不超过m的最大子序和。
解题思路
用前缀和,我们可以枚举最右边的点,然后取左边合法范围内最小的前缀和,这个我们可以用单调队列进行优化。
code
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m,x,sum[300001],head,tail,q[300001],ans;
int main()
{scanf("%d%d",&n,&m);head=1;tail=0;for (int i=1;i<=n;i++){while (head<=tail&&q[head]+m<i) head++;//维护合法区域scanf("%d",&x);sum[i]=sum[i-1]+x;ans=max(ans,sum[i]-sum[q[head]]);//取最大值while (head<=tail&&sum[q[tail]]>sum[i]) tail--;//维护单调性q[++tail]=i;//加入队列}printf("%d",ans);
}