zoukankan      html  css  js  c++  java
  • 【k长度最大连续子序和】 最大子序和

    传送门

    题意

    长度为(n)的整数序列,找出一段长度不超过(m)的和最大的连续子序列

    数据范围

    (1leq n leq 3·10^{5})

    题解

    • 预处理前缀和,贪心法,假如右端点(i)固定,找到一个左端点(j in [i-m,i-1])(s_{j})要尽量的小,

    • 为了使得区间和最大,(j)的取值,是一个区间,我们只要这个区间的最值。区间最值,就可以通过单调队列处理。

    • 如果有一个位置(k)(k<j<i).而且(sum_{k}geq sum_{j}),那么(sum_{i}-sum_{k} leq sum_{i} -sum_{j})

      • 也就是说(j)更靠近 (i) ,不易超过限制(m),并且答案更优,那么(k)是没有用了。所以每次更新的时候先把越界的队头去除,剩下的显然就是最优解

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define rep(i,a,n) for(int i=a;i<n;i++)
    const int N=3e5+10;
    int s[N];
    int n,m;
    int ans=-1e9;
    
    deque<int>q;
    
    int main()
    {
        scanf("%d%d",&n,&m);
    
        rep(i,1,n+1)
        {
            scanf("%d",&s[i]);
            s[i] += s[i-1];
        }
        q.push_back(0);
        rep(i,1,n+1)
        {
            while(q.size() && i-m>q.front()) q.pop_front();
            ans=max(ans,s[i]-s[q.front()]);
            while(q.size() && s[q.back()]>=s[i]) q.pop_back();
            q.push_back(i);
        }
        printf("%d",ans);
    }
    
    
  • 相关阅读:
    C语言程序设计II—第六周教学
    第一次结对编程情况反馈
    C语言程序设计II—第五周教学
    C语言程序设计II—第四周教学
    放缩
    切线垂直
    指数为对数时取对数
    整体运算
    数列求通项+离散数列单调性判断
    整体运算+求零点
  • 原文地址:https://www.cnblogs.com/hhyx/p/13711226.html
Copyright © 2011-2022 走看看