tyvj/joyOI 1305-最大子序和【单调队列】

正题

题目链接: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);
}

猜你喜欢

转载自blog.csdn.net/Mr_wuyongcong/article/details/81706309