【算法设计】最大子段和问题
2012-03-29 23:16
337 查看
(一) 问题描述
输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值,并给出子段起始地址。
(二) 算法设计
2.1简单算法
看到这道题最简单的算法即依次计算从1到n内所有可能子段和,以sum记录最优值。代码如下:
复杂度是O(n3)
2.2 优化
容易看出,2.1中代码出现大量的重复计算,即在第三个for里,由于
,因此大可以利用变量this_sum记录上一个上一个停止下标(同一个开始下标i)的求和。代码如下:
复杂度为O(n2)
2.3 动态规划
求1到j里的最大段和问题可将问题分为:求1到j-1的最大子段和与含有了j的最大子段和的比较问题,表达式如下
C[j]=max(C[j-1],t[j]),
其中C[j]表示1到j的最大子段和,t[j]表示以j结束的最大子段和。代码如下:
利用sum记录已有的最优值即C[j-1],利用this_sum计算加上a[j]后的值。若this_sum大于sum,则更新sum,并继续该过程;若this_sum小于等于0,则可将this_sum重新置于0,更新其实坐标为j+1,开始新一轮的探试累加(详见后文);若this_sum仅仅只是小于sum,则可继续累加。
当this_sum小于等于0时之所以可以开始新一轮的子段累加:
输入一个整形数组,数组里有正数也有负数。数组中连续的一个或多个整数组成一个子数组,每个子数组都有一个和。求所有子数组的和的最大值,并给出子段起始地址。
(二) 算法设计
2.1简单算法
看到这道题最简单的算法即依次计算从1到n内所有可能子段和,以sum记录最优值。代码如下:
int maxSum_sim(int a[],int n){ int sum=0,this_sum=0; int besti,bestj; for(int i=0;i<n;i++) for(int j=i;j<n;j++){ this_sum=0; for(int k=i;k<=j;k++) this_sum+=a[k]; if(this_sum>sum){ sum=this_sum; besti=i; bestj=j; } } printf("%d %d\n",besti,bestj); return sum; }
复杂度是O(n3)
2.2 优化
容易看出,2.1中代码出现大量的重复计算,即在第三个for里,由于
,因此大可以利用变量this_sum记录上一个上一个停止下标(同一个开始下标i)的求和。代码如下:
int maxSum_sim2(int a[],int n){ int sum=0,this_sum=0; int besti=0,bestj=0; for(int i=0;i<n;i++){ this_sum=0; for(int j=i;j<n;j++){ this_sum+=a[j]; if(this_sum>sum) { sum=this_sum; besti=i; bestj=j; } } } printf("%d %d\n",besti,bestj); return sum; }
复杂度为O(n2)
2.3 动态规划
求1到j里的最大段和问题可将问题分为:求1到j-1的最大子段和与含有了j的最大子段和的比较问题,表达式如下
C[j]=max(C[j-1],t[j]),
其中C[j]表示1到j的最大子段和,t[j]表示以j结束的最大子段和。代码如下:
int maxSum_DP(int a[],int n){ int sum=0,this_sum=0; int besti=0,bestj=0; int i=0; for(int j=0;j<n;j++){ this_sum+=a[j]; if(this_sum>sum){ sum=this_sum; besti=i; bestj=j; } else if(this_sum<=0){ i=j+1; this_sum=0; } } printf("%d-->%d\n",besti,bestj); return sum; }
利用sum记录已有的最优值即C[j-1],利用this_sum计算加上a[j]后的值。若this_sum大于sum,则更新sum,并继续该过程;若this_sum小于等于0,则可将this_sum重新置于0,更新其实坐标为j+1,开始新一轮的探试累加(详见后文);若this_sum仅仅只是小于sum,则可继续累加。
当this_sum小于等于0时之所以可以开始新一轮的子段累加:
假设最终子段∑中包括了该子段∑1,剩下的子段是∑2,即 ∑=∑1+∑2,且∑=maxValue ∵ ∑1<=0 ∴∑-∑2<=0,即∑2>=∑。 这与∑=maxValue矛盾,所以假设不成立。 ∴在最终的∑中必定不包含∑1。
相关文章推荐
- 【算法设计】最大子段和问题解析(对应算法第三题)
- 【算法设计与分析】最大子段和问题
- 【算法设计】最大子段和问题解析(对应算法第三题)
- 【算法设计】最大子段和问题解析(对应算法第三题)
- 【算法设计】最大子段和问题解析(对应算法第三题)
- 【算法学习笔记】19.算法设计初步 最大子列和问题的三种方法
- 【算法】最大子段和问题
- 三种算法实现最大子段和问题(Java实现)
- 【算法学习笔记】19.算法设计初步 最大子列和问题的三种方法
- 算法设计--求连续子向量的最大和问题--论想法思路的重要性
- [算法]最大子段和问题
- 从最大子段和问题看算法的优化问题
- 从最大子段和问题看算法的优化问题
- 【算法设计与数据结构】二分法解决最大值最小化问题——入门篇
- 算法分析与设计-10- 最大子段和的动态规划算法
- 算法设计与分析不定期更新的日常之最大子段和四种方法
- 【算法设计】最大子矩阵问题
- 从最大子段和问题看算法的优化问题
- 最大间隙问题。给定 n 个实数,求这n个实数在数轴上相邻2个数之间的最大差值,设计解最大间隙问题的线性时间算法。
- 【算法设计】最大子矩阵问题