homework-01 最大子串和
题目描述
对于一个给定的数列,求该数列最大的子串和(连续)
问题分析
处理发生区间上的问题时,经常会用一个非常简单经典的思路——部分和(也有叫前缀和)。部分和的思想在很多复杂的区间上的算法中都有应用,它解决的问题是,在一个序列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 最大子串和的更多相关文章
- 【做题】CF1045(ABH)
原文链接https://www.cnblogs.com/cly-none/p/9697662.html 题目当然不会做完了,这里只讲有做&会做的. A. Last chance 题意:有\(n ...
- HDU-1041-Computer Transformation,大数递推,水过~~
Computer Transformatio ...
- 1393 0和1相等串 51nod
1393 0和1相等串 基准时间限制:1 秒 空间限制:131072 KB 分值: 20 难度:3级算法题 收藏 关注 给定一个0-1串,请找到一个尽可能长的子串,其中包含的0与1的个数相等. I ...
- LOJ 3184: 「CEOI2018」斐波那契表示法
题目传送门:LOJ #3184. 题意简述: 题目说得很清楚了. 题解: 首先需要了解「斐波那契数系」为何物. 按照题目中定义的斐波那契数列 \(F_n\),可以证明,每个非负整数 \(n\) 都能够 ...
- 【USACO 3.1】Contact(01子串按出现次数排序)
题意:给你一个01字符串,将长度为a到b之间(包含a.b)的子串按照出现次数排序.注意输入输出格式 题解:01子串对应一个二进制,为了区别11和011这样的不同子串,我们把长度也记录下来,官方题解是在 ...
- 2019牛客暑期多校赛(第三场)B-求01串中的最长01数量相等的子串和子序列
https://ac.nowcoder.com/acm/contest/883/B 首先先把0所在的位置变-1,1所在位置变1,然后统计一个前缀和,用sum[i]表示. 那么如果从起点开始的话只要满足 ...
- Java实现固定长度得01子串
固定位数得01子串 Description 对于长度为n的一个01串,每一位都可能是0或1,一共有2 ^n 种可能.请按从小到大的顺序输出这2^n种01串. Input 包含多组数据,每组数据占一行, ...
- 算法进阶面试题01——KMP算法详解、输出含两次原子串的最短串、判断T1是否包含T2子树、Manacher算法详解、使字符串成为最短回文串
1.KMP算法详解与应用 子序列:可以连续可以不连续. 子数组/串:要连续 暴力方法:逐个位置比对. KMP:让前面的,指导后面. 概念建设: d的最长前缀与最长后缀的匹配长度为3.(前缀不能到最后一 ...
- 最长相同01数的子串(map搞搞)--牛客第三场 -- Crazy Binary String
题意: 如题. 或者用我的数组分治也可以,就是有点愚蠢. //#include <bits/stdc++.h> #include <map> #include <iost ...
- poj3294 出现次数大于n/2 的公共子串
Life Forms Time Limit: 5000MS Memory Limit: 65536K Total Submissions: 13063 Accepted: 3670 Descr ...
随机推荐
- DNS子域委派配置案例[转载]
最近在研究linux dns 在51上面看见这篇文章,感觉讲的很透彻,随转载,方便以后自己查阅 原文地址:http://www.51osos.com/a/Linux_CentOS_RedHat/Lin ...
- 【转载】R6034错误,C Runtime Error
能查到的解决方法都在里面有提及: 我是使用 stdafx.h加入这句 code #pragma comment(linker, "\"/manifestdependency:typ ...
- Java根据html模板创建 html文件
1.创建html的java代码 package com.tydic.eshop.util; import java.io.FileInputStream; import java.io.FileOut ...
- .net 生成拼音码与五笔码
首先加入配置文件: <?xml version="1.0" encoding="utf-8" ?> <CodeConfig> <S ...
- c扩展调用php的函数(调用实现php函数的c函数)
上一次是写的c扩展调用c的标准函数,但是只能调用头文件中申明的函数,今天来说下c扩展调用实现php函数的c函数,比方说,c扩展要用到php中ip2long这个函数,但是c不可能去php中调用,肯定是去 ...
- JAVA中,不同工程间的方法调用
可以调用, 用配置构建路径的方法:点选工程1, 点击右键, 选择 Build Path(构建路径) - > Configure Build Path...(配置构建路径...)然后在弹出的窗口中 ...
- NGUI监听事件
using UnityEngine; using System.Collections; public class UIDataHandler : MonoBehaviour { public UII ...
- UVA 821 Page Hopping 网页跳跃(BFS,简单)
题意: 给一个无权有向图,可认为边的长度为1,求两点间的平均长度(即所有点对的长度取平均),保留3位小数.保证任意点对都可达. 思路: 简单题.直接穷举每个点,进行BFS求该点到其他点的距离.累加后除 ...
- directdraw显示yuv视频,出现屏保时,yuv显示不出来,表面丢失
原因是: DDrawSurface 丢失, DDraw表面在很多情况下都会丢失(如:启动其他全屏独占程序,屏保,或锁屏时), 表面丢失其实就是表面所使用的内存或显存被DirectDraw系统释放, 分 ...
- hdu 2204 Eddy's爱好
// 一个整数N,1<=N<=1000000000000000000(10^18).// 输出在在1到N之间形式如M^K的数的总数// 容斥原理// 枚举k=集合{2,3,5,7,11,1 ...