题目描述

  对于一个给定的数列,求该数列最大的子串和(连续)

问题分析

  处理发生区间上的问题时,经常会用一个非常简单经典的思路——部分和(也有叫前缀和)。部分和的思想在很多复杂的区间上的算法中都有应用,它解决的问题是,在一个序列a[1..n]中快速求得任意子串a[n] + a[n + 1] + ... a[n + m]的和,具体过程非常简单,在原序列里,a[i]保存了在序列中第i个位置的数值,根据原序列生成一个新数列s[1..n],其中s[j] = sum{a[i], 0 <= i <= j},那么对于任意子串和就有a[p..q]=s[q]-s[p-1]。这样以来我们就可以在相同的空间复杂度下快速访问更多信息,这样完全不用保留原数组,因为对于任意原数组中的数值都有a[i] = s[i]-s[i-1]。有了新工具我们再来考虑原问题,先从最简单的思路,问题要求找出最大子串和,那么就枚举每一个子串的起始位置,找一个最大的子串,公式表示就是ans=max{s[j]-s[i],0<=i<=j,0<j<=n},从这个式子可以发现,任意子串和都有sum=s[j]-s[i],(0<=i<=j)的形式,其中s[j]的数值固定不同,那么我们只需要找到min{s[i],0<=i<j}就能找到以j结尾最大的子串,这个工作只要的经过简单的预处理就可以得到,那么我们最后实际需要做的工作就是枚举一遍子串的结尾点,结算该结尾最大的子串,并统计其中最大值即可,时空复杂度均为O(n)。

  除了以上解法,我还在其他同学的博客发现了一些其他更好的解法,事实上我们发现一个序列里的数有正有负,其中最大子串是其中一些连续的数,这些数也是有正有负的,但其中真正“做出贡献”的只有正数,我们选取了一段负数是因为在这段负数的前后必定有贡献比其损失更多的正数,所以可以简单地得到一个结论,最大子串首尾必须是正数,(如果有一段时负数的话那么去掉这一段得到的子串比原来更大,与假设矛盾)。根据这个结论我们可以得到一个新的算法,把原数列分成正数段和负数段

原序列:
a=[1 - - - - 5]
划分后:
() (- -) ( ) (- -) ( )
b=[1 - - 12]

在新数列上我们枚举每一正数作为起点,然后不断加上他的后继,若当前结果优于已得到的答案则更新答案,当加入一个后继发现当前结果小于等于0时,就结束这次操作找下一个正数迭代。先在简单证明一下它的合理性,前面已经说明了最大子串肯定开始与正数,那么仅需证在每次枚举起始点的操作中都考虑到了所有情况,假设当前起始点为i,结尾枚举到了j时发现b[i..j]<=0,那么对于任意以j+1起始的子串来说,b[i..j] + b[j..k] < b[j..k],因此吧b[i..k]不会比b[j..k]更优,无需进行后面的枚举,证毕。但是现在看来这个算法最坏的时间复杂度是O(n^2),比前者逊色不少,但是这个算法还能再优化,如果以第i个位置为起点的查找到j点结束了,且存在一个b[k]>0,i<k<j,那么对于任意b[k..m],b[i..m]都会比b[k..m]优,因为在枚举过程中保证了b[i..k]>0,同时也保证了b[k..j]<0,那么当我们枚举到j结束之后以j+1处的元素为起始点继续枚举即可,如果全是非正数的话输出最大元素即可,这样这个算法就达到了O(n)的时间复杂度,达到了和前面算法一样的效率。

一些讨论

  第二个算法想写上转载地址,但是实在懒得找了,原作者介意的话请速与我联系。在原博中作者自语此法为奇技淫巧(大概同意,忘了原话了),与标准答案略有差距,我个人还是非常喜欢这种接法的, 通过发现问题的新的性质来解决问题本身就会加深对问题的理解,同时带来新的启发,而且这种方法同表程相比代码长度,时空复杂度,思维难度大体相当,没有孰优孰劣之分。有了这些方法原题目现在看上去就so easy了,我们可以简单思考一下扩展问题。

求最小子串和;只需简单给每个数转换正负。

序列尾部会增加或删除元素;在第一种方案中给每个点记录一下当前状态,增删后从断点继续计算即可。

序列长度固定,其中一些元素的值会改变;可以使用标程中O(nlogn)的算法,将每次计算的节点信息保留,元素改变后同时改变影响的节点,时间复杂度为O((m+n)logn),其中m为改变的次数。

序列内部的元素会删除增加,没有想到什么更好的办法。

最大子串积,。。。。。

模m下的最大子串积,。。。。。

其他

  我选择的参考书是第二版的《代码大全》

homework-01 最大子串和的更多相关文章

  1. 【做题】CF1045(ABH)

    原文链接https://www.cnblogs.com/cly-none/p/9697662.html 题目当然不会做完了,这里只讲有做&会做的. A. Last chance 题意:有\(n ...

  2. HDU-1041-Computer Transformation,大数递推,水过~~

                                                                                  Computer Transformatio ...

  3. 1393 0和1相等串 51nod

    1393 0和1相等串 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题  收藏  关注 给定一个0-1串,请找到一个尽可能长的子串,其中包含的0与1的个数相等. I ...

  4. LOJ 3184: 「CEOI2018」斐波那契表示法

    题目传送门:LOJ #3184. 题意简述: 题目说得很清楚了. 题解: 首先需要了解「斐波那契数系」为何物. 按照题目中定义的斐波那契数列 \(F_n\),可以证明,每个非负整数 \(n\) 都能够 ...

  5. 【USACO 3.1】Contact(01子串按出现次数排序)

    题意:给你一个01字符串,将长度为a到b之间(包含a.b)的子串按照出现次数排序.注意输入输出格式 题解:01子串对应一个二进制,为了区别11和011这样的不同子串,我们把长度也记录下来,官方题解是在 ...

  6. 2019牛客暑期多校赛(第三场)B-求01串中的最长01数量相等的子串和子序列

    https://ac.nowcoder.com/acm/contest/883/B 首先先把0所在的位置变-1,1所在位置变1,然后统计一个前缀和,用sum[i]表示. 那么如果从起点开始的话只要满足 ...

  7. Java实现固定长度得01子串

    固定位数得01子串 Description 对于长度为n的一个01串,每一位都可能是0或1,一共有2 ^n 种可能.请按从小到大的顺序输出这2^n种01串. Input 包含多组数据,每组数据占一行, ...

  8. 算法进阶面试题01——KMP算法详解、输出含两次原子串的最短串、判断T1是否包含T2子树、Manacher算法详解、使字符串成为最短回文串

    1.KMP算法详解与应用 子序列:可以连续可以不连续. 子数组/串:要连续 暴力方法:逐个位置比对. KMP:让前面的,指导后面. 概念建设: d的最长前缀与最长后缀的匹配长度为3.(前缀不能到最后一 ...

  9. 最长相同01数的子串(map搞搞)--牛客第三场 -- Crazy Binary String

    题意: 如题. 或者用我的数组分治也可以,就是有点愚蠢. //#include <bits/stdc++.h> #include <map> #include <iost ...

  10. poj3294 出现次数大于n/2 的公共子串

    Life Forms Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 13063   Accepted: 3670 Descr ...

随机推荐

  1. netty websocket协议开发

    websocket的好处我们就不用多说了,就是用于解决长连接.服务推送等需要的一种技术. 以下我们来看一个例子: package com.ming.netty.http.websocket; impo ...

  2. SQL 分组排序分页(大神帮写的膜拜一下)

    查询全部: SELECT P3.ID, P3.Name, P3.AddTimeFROM (SELECT Name, MAX(AddTime) AS MaxAddTime FROM Product AS ...

  3. windows线程同步

    一.前言 之前在项目中,由于需要使用到多线程,多线程能够提高执行的效率,同时也带来线程同步的问题,故特此总结如下. 二.windows线程同步机制 windows线程同步机制常用的有几种:Event. ...

  4. 1176. Hyperchannels(欧拉回路)

    1176 给定一有向图 求其反图的欧拉回路 路径输反了 一直WA.. #include <iostream> #include<cstdio> #include<cstr ...

  5. JAVA将Excel中的报表导出为图片格式(三)换一种实现

    上一篇介绍了使用Java的Robot机器人实现截图,然后将剪贴板上的数据流生成PNG图片 但是经过博主的不断测试,在完全依赖远程桌面的没有终端显示器的服务器上 使用截图方式是不可行的,因为一旦使用了远 ...

  6. UVA 10972 RevolC FaeLoN(边连通分量)

    坑了我一天的题目..跑了20ms挂了,就知道有个小毛病= = 无向图转有向图判强连通. 首先要知道什么样的无向图可以转化为强连通图?连通分量(环)自然是可以的:那么扩大范围(存在割顶),发现点连通分量 ...

  7. 【iOS-cocos2d-X 游戏开发之九】Cocos2dx利用CCSAXParser解析xml数据&CCMutableDictionary使用与注意!

    本站文章均为李华明Himi原创,转载务必在明显处注明:转载自[黑米GameDev街区] 原文链接: http://www.himigame.com/iphone-cocos2dx/694.html ☞ ...

  8. 常见的js函数

    改变元素的样式   var  changeStyle = function(elem,name,value){      elem.style[name] = value; }   空位补零   fu ...

  9. 解决Jsoup网页抓取过程中需要cookie的问题

    最近在做城觅网的信息抓取,发现城觅网上海与北京的url是一样的.那怎样才确定信息的来源呢?折腾了半天,才发现城觅网是使用cookie的,如果你把网站的cookie禁用了,就无法在上海与北京之间切换了. ...

  10. 基于Spring AOP实现对外接口的耗时监控

    AOP是Spring的核心,Spring不但自身对多种框架的集成是基于AOP,并且以非常方便的形式暴露给普通使用者.以前用AOP不多,主要是因为它以横截面的方式插入到主流程中,担心导致主流程代码不够清 ...