zoukankan      html  css  js  c++  java
  • ContestHunter 1201 最大子序和

    描述

    输入一个长度为n的整数序列,从中找出一段不超过m的连续子序列,使得整个序列的和最大。

    例如 1,-3,5,1,-2,3

    当m=4时,S=5+1-2+3=7
    当m=2或m=3时,S=5+1=6

    输入格式

    第一行两个数n,m(n,m<=300000)
    第二行有n个数,要求在n个数找到最大子序和

    输出格式

    一个数,数出他们的最大子序和

    样例输入

    6 4
    1 -3 5 1 -2 3

    样例输出

    7
    这题是单调队列的典型题。首先可以把区间和问题转换为两个前缀和相减的问题。朴素算法就是枚举左右端点,但算法复杂度为O(n^2),这道题显然是过不了的。
    所以我们可以只枚举右端点i,当i固定时,找一个左端点j,其中j属于[i-m,i-1]并且sum[j]最小。
    不妨比较一下任意两个位置j和k,如果k<j<i并且是sum[k]>=sum[j],那么对所以大于等于i的右端点来说,k都不会是一个好选择,直接移除队列比较好。
    代码如下
    #include<bits/stdc++.h>
    using namespace std;
    int a[300005],q[300005],sum[300005];
    int main() 
    {
    int n,m;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    cin>>a[i];
    for(int i=1;i<=n;i++)
    {
        sum[i]=sum[i-1]+a[i];
    }
    int l=1,r=1,ans=-99999999;
    q[1]=0;
    for(int i=1;i<=n;i++)
    {
        while(l<=r&&q[l]<i-m)
        l++;
        ans=max(ans,sum[i]-sum[q[l]]);
        while(l<=r&&sum[q[r]]>=sum[i])
        r--;
        q[++r]=i;
    }
    cout<<ans<<endl;
    
       return 0;
    }




  • 相关阅读:
    MySQL sys Schema 简单介绍-2
    dubbo服务+Spring事务+AOP动态数据源切换 出错
    sql 查询优化
    spring事务-说说Propagation及其实现原理
    Redis 分布式锁
    三、操作符
    二、一切皆是对象
    一、对象导论
    SpringMVC工作原理
    数据库性能优化策略
  • 原文地址:https://www.cnblogs.com/hh13579/p/10864463.html
Copyright © 2011-2022 走看看