最大连续区间和问题 —— 转自purplest C++博客
来源:互联网 发布:网站seo综合诊断 编辑:程序博客网 时间:2024/06/05 15:45
今天正好做到一道有关"最大子矩阵问题"的题目,可以分解成最大连续区间和问题。看到这篇文章不错,顺便转载过来。
原文地址: http://www.cppblog.com/purplest/archive/2013/03/04/198199.html, 转载请说明出处
最大连续区间和是一个经典的问题。给定一个长度为n的序列a[1],a[2]...a[n-1],a[n],求一个连续的子序列a[i],a[i+1]...a[j-1],a[j],使得a[i]+a[i+1]...a[j-1]+a[j]最大。
①最简单最容易想到的就是根据定义来枚举。
枚举上下界{i,j | 0<=i<=j<=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));
②其实就是第一种方法的优化。
这里有个很容易想到的优化,即预处理出前缀和sum[i]=a[0]+a[1]+...+a[i-1]+a[i],算区间和的时候即可将求区间和的复杂度降到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]);
③可以利用动态规划的思维来继续优化,得到一个线性的算法,也是最大连续区间和的标准算法
定义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);}
④同样用到类似的思维。
首先也需要预处理出前缀和sum[i],可以推出ans=max{sum[i]-min{sum[j] } | 0<=j<i<=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]);}
总结:虽然朴素的O(n^3)和前缀和优化的O(n^2)算法很容易想到,但代码实现却反而比方法三麻烦,第四个方法虽然有和方法三相同的复杂度,但需要一个预处理和多出的O(n)的空间,所以,方法三很好很强大。
- 最大连续区间和问题 —— 转自purplest C++博客
- 连续最大和,数字类区间问题
- 最大子数组(最大连续区间和)问题
- 最大连续区间和算法、
- 连续最大和自数组
- 最大连续和问题
- 最大连续和问题
- 【贪心\最大连续区间和】游览路线
- hrbust 1684 最大连续和(区间合并)
- uva1400 区间最大连续和 线段树
- C#连续区间最大和求解
- UVA - 1400(区间连续最大和)
- 最大连续环区间和-dp
- 最大连续区间和的算法总结
- 100道动态规划——21 HDU 1559 最大子矩阵和 树状数组 最大连续子区间和
- 经典算法——连续子数组最大和问题
- 求最大连续和问题
- 求最大连续和——dp
- java内存溢出示例(堆内存、栈内存)
- Nginx开发从入门到精通三
- 虚拟机搭建Hadoop集群(1) ---nat模式
- python中的urlencode与urldecode
- SQLmap
- 最大连续区间和问题 —— 转自purplest C++博客
- 黑马程序员------Java缓存—浅谈Memcached
- C++ const 用法总结
- ZOJ 3782 Ternary Calculation
- Nginx开发从入门到精通四
- Java实现KMP算法
- MFC 树控件我喜欢的两个函数
- make uImage 与make iImage的区别
- ZOJ 3785 What day is that day?