zoukankan      html  css  js  c++  java
  • #2019121200026 最大子序列和

    题目描述

    给定一段序列,从(a[1])(a[n]),求满足条件的(1leq ileq jleq n),使得(sumlimits^j_{k=i}a[k])最大.

    题解

    1

    最简单最容易想到的就是根据定义来枚举。
    枚举上下界({(i,j) | 1leq ileq jleq n}),维护一个(max)值即可。
    其中枚举上下界的时间复杂度为(O(n^2)),求区间和的复杂度为(O(n)),所以总时间复杂度为(O(n^3))

    for ( int i = 1 ; i <= n ; i++ )
        for ( int j = i ; j <= n ; j++ )
            ans = max(ans,accumulate(a+i,a+j+1,0));
    

    2

    其实就是第一种方法的优化。
    这里有个很容易想到的优化,即预处理出前缀和(sum[i]=sumlimits_{h=1}^ia[h]),算区间和的时候即可将求区间和的复杂度降到(O(1)),枚举上下界的复杂度不变,所以总时间复杂度为(O(n^2))

    for ( int i = 1 ; i <= n ; i++ )
        sum[i]=sum[i-1]+a[i];
    for ( int i = 1 ; i <= n ; i++ )
        for ( int j = i ; j <= n ; j++ )
            ans = max(ans,sum[j]-sum[i-1]);
    

    3

    可以利用动态规划的思维来继续优化,得到一个线性的算法,也是最大连续区间和的标准算法
    定义(maxn[i])为以(i)为结尾的最大连续和,则很容易找到递推关系:(maxn[i]=max {0,maxn[i-1]}+a[i])
    所以只需要扫描一遍即可,总时间复杂度为(O(n))

    for ( int i = 1 ; i <= n ; i++ )
    {
        last = max(0,last)+a[i];
        ans = max(ans,last);
    }
    

    4

    同样用到类似的思维。
    首先也需要预处理出前缀和(sum[i]),可以推出(ans=max {sum[i]-min {sum[j]} | 0leq j<ileq n })
    而最小前缀和可以动态维护,所以总时间复杂度为(O(n))

    for ( int i = 1 ; i <= n ; i++ )
        sum[i]=sum[i-1]+a[i];
    for ( int i = 1 ; i <= n ; i++ )
    {
        ans = max(ans,sum[i]-minn);
        minn = min(minn,sum[i]);
    }
    
    要做就做南波万
  • 相关阅读:
    第一个python的GUI程序
    vbs实现打开记事本,写入一些文字,复制然后关闭
    自己制作的autoitX的vbs脚本,用来自动配置金山毒霸2011局域网更新
    使用免费的unrar.exe解压rar文件
    初学写的几个autoit小程序
    vba调用AutoItX3的Activex控件,实现doc2Html源码
    网页制作相关工具
    vbs自动登陆115网盘代码
    深搜和宽搜的c++实现
    入职一个月有感
  • 原文地址:https://www.cnblogs.com/liuziwen0224/p/12031413.html
Copyright © 2011-2022 走看看