最大连续子段和的两种线性算法

问题描述:给一个数组a1,a2,...,an.求这个数组的最大连续子段和。(非空子段)

即,定义Sij=ai+...+aj,则题目要求的是 max{Sij}(1<=i<=j<=n)

N^3枚举和优化之后的N^2枚举就不说了,还有NlogN的二分算法也不提,想了解的可以看我的另一篇博客:http://www.cnblogs.com/itlqs/p/5097504.html

这里主要详解两种O(n)的算法。

方法一:动态规划

  dp[i]表示以第i位为结尾的最大子段和。那么转移方程就是:dp[1]=a[1],dp[i]=max{dp[i-1]+a[i],a[i]} (i>=2)

  以第i位为结尾的最大子段和,要么是它接上了前一个的最大子段和,要么就是它自己。

  最后的结果就是扫一遍dp[1..n]的最大值。

方法二:前缀和

  前缀和Sn=a1+...+an可以预处理出来。(S0=0)

  则Sij=ai+...+aj=Sj-Si-1

  题目要求的实际上就是max{Sij}=max{Sj-Si-1}=max{Sj-min{Si-1}}(1<=i<=j<=n)

  那么也就是说,对于每一个Sj,我们都要找它前面的最小的一个前缀和减掉,那么这个min{Si-1}是可以动态维护的,所以O(n)扫一遍结果就出来了。

时间: 2024-10-07 15:43:28

最大连续子段和的两种线性算法的相关文章

【转】两种非对称算法原理:RSA和DH

转自:http://blog.chinaunix.net/uid-7550780-id-2611984.html 两种非对称算法原理:RSA和DH 虽然对称算法的效率高,但是密钥的传输需要另外的信道.非对称算法RSA和DH可以解决密钥的传输问题(当然,它们的作用不限于此).这两个算法的名字都是来自于算法作者的缩写,希望有朝一日能够出现用中国人命名的加密算法.非对称算法的根本原理就是单向函数,f(a)=b,但是用b很难得到a. RSA算法 RSA算法是基于大数难于分解的原理.不但可以用于认证,也可

集合相似度对比的两种计算算法

相似度对比的两种计算算法:Jaccard similarity相似性系数和Ochiai coefficient落和系数 Jaccard coefficient:A,B分别代表符合某种条件的集合:两个集合交集的大小/两个集合并集的大小,交集=并集意味着2个集合完全重合. Ochiai coefficient:A,B分别代表符合某种条件的集合:两个集合的交集大小/两个集合大小的几何平均值.是余弦相似性的一种形式. 相关参考链接:http://en.wikipedia.org/wiki/Jaccard

经典的两种排序算法

一.冒泡排序 int temp = 0; for (int j = 1; j < a.Length; j++) { for (int i = 0; i < a.Length - j; i++)//内循环,每走一趟会把最小值放到最后 { if (a[i] < a[i + 1]) { temp = a[i]; a[i] = a[i + 1]; a[i + 1] = temp; } } } 二.选择法排序 int min; for (int j = 0; j< a.Length; j++

算法—比较两种排序算法:选择排序和插入排序

现在我们已经实现了两种排序算法,我们很自然地想知道选择排序和插入排序哪种更快.这里我们第一次用实践说明我们解决这个问题的办法. 性质:对于随机排序的无重复主键的数组,插入排序和选择排序的运行时间是平方级别的,两者之比应该是一个较小的常数. 例证:这个结论在过去的半个世纪中已经在许多不同类型的计算机上经过了验证.在1980年本书第一版完成之时插入排序就比选择排序快一倍,现在仍然是这样,尽管那时这些算法将10万条数据排序需要几个小时而现在只需要几秒钟.在你的计算机上插入排序也比选择排序快一些吗?可以

[算法模版]Tarjan爷爷的两种图论算法

[算法模版]Tarjan爷爷的两种图论算法 前言 Tarjan爷爷发明了很多图论算法,这些图论算法有很多相似之处(其中一个就是我都不会).这里会对这三种算法进行简单介绍. 定义 强连通(strongly connected): 在一个有向图\(G\)里,设两个点$ a, b \(发现,由\)a\(有一条路可以走到\)b\(,由\)b\(又有一条路可以走到\)a\(,我们就叫这两个顶点\)(a,b)$强连通. 强连通图: 如果 在一个有向图\(G\)中,每两个点都强连通,我们就叫这个图,强连通图.

两种插入排序算法java实现

两种方法都编译运行通过,可以当做排序类直接使用. 折半插入排序: public class Sort1 { public static void main(String[] args) { InsertSort sort = new InsertSort(); sort.InsertSort(); int[] arr = sort.getarr(); System.out.println(); System.out.println("排序之后:"); for (int ar : arr

一列数字的规则如下;1,1,2,3,5,8,13,21,34........ 求第30位数字是多少,用递规和非递归两种方法算法实现

斐波纳契数列(Fibonacci Sequence),又称黄金分割数列.在数学上,斐波纳契数列以如下被以递归的方法定义:F0=0,F1=1,Fn=F(n-1)+F(n-2)(n>=2,n∈N*)在现代物理.准晶体结构.化学等领域,斐波纳契数列都有直接的应用,现在我从算法的角度,利用递归和非递归两种方式来进行实现: 一:递归 这个数列是用递归来实现的经典例子. private static  long Fibonacci(int n)         {             long resu

两种快速排序算法性能的比较

先来看看第一种快速排序算法(QuickSort1): #include <iostream> #include <fstream> #include <ctime> #define MAXNUM 1024 using namespace std; void QuickSort(int A[], int low, int high) { if(low>=high) return; int first = low; int last = high; int key =

mysql 排序长度限制之max_length_for_sort_data以及mysql两种排序算法

SET max_length_for_sort_data = 1024 SHOW VARIABLES LIKE '%max_length_for_sort_data%'; 查询:SELECT * FROM CS_COLUMNS ORDER BY table_name,column_name LIMIT 0,100 错误代码: 1815Internal error: IDB-2015: Sorting length exceeded. Session variable max_length_for