#include<iostream>
using namespace std;
const int MAXN = 1e5;
int MaxSubseqSum1(int a[], int n){//O(N^3)
int ThisSum, MaxSum = 0;
for(int i = 0; i < n; i++){
for(int j = i; j < n; j++){
ThisSum = 0;
for(int k = i; k <= j; k++){
ThisSum += a[k];
}
if(ThisSum > MaxSum){
MaxSum = ThisSum;
}
}
}
return MaxSum;
}
int MaxSubseqSum2(int a[], int n){//O(N^2)
int ThisSum, MaxSum = 0;
for(int i = 0; i < n; i++){
for(int j = i; j < n; j++){
ThisSum += a[j];
if(ThisSum > MaxSum){
MaxSum = ThisSum;
}
}
}
return MaxSum;
}
//分而治之 O(N*log(N))
/*返回三个整数的最大值*/
int Max3 ( int A, int B, int C ) {
return (A > B) ? (A > C ? A : C) : (B > C ? B : C);
}
/*分治法球List[left]到List[right]的最大子列和*/
int DivideAndConquer ( int List[], int left, int right ) {
int MaxLeftSum, MaxRightSum; //存放左右子问题的解。
int MaxLeftBorderSum, MaxRightBorderSum; //存放跨分界线的结果。
int LeftBorderSum, RightBorderSum;
int center, i;
/*递归的终止条件,子列只有1个数字*/
if ( left == right ) {
if ( List[left] > 0 ) return List[left];
else return 0;
}
/* “分”的过程 */
center = ( left + right ) / 2; //找到中分点。
MaxLeftSum = DivideAndConquer ( List, left, center ); //递归求左子列和。
MaxRightSum = DivideAndConquer ( List, center+1, right ); //递归求右子列和。
/*求跨分界线的最大子列和*/
MaxLeftBorderSum = 0; LeftBorderSum = 0;
for ( i = center; i >= left; i-- ) {
LeftBorderSum += List[i];
if ( LeftBorderSum > MaxLeftBorderSum )
MaxLeftBorderSum = LeftBorderSum;
}//左边扫描结束。
MaxRightBorderSum = 0; RightBorderSum = 0;
for ( i = center+1; i <= right; i++ ) {
RightBorderSum += List[i];
if ( RightBorderSum > MaxRightBorderSum )
MaxRightBorderSum = RightBorderSum;
}//右边扫描结束。
/*返回“治”的结果*/
return Max3 ( MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum );
}
/*此函数用于保持接口相同*/
int MaxSubseqSum3 ( int List[], int N ) {
return DivideAndConquer ( List, 0, N-1 );
}
int MaxSubseqSum4(int a[], int n){//在线处理 O(N)
int ThisSum = 0, MaxSum = 0;
for(int i = 0; i < n; i++){
ThisSum += a[i];
if(ThisSum > MaxSum)//发现更大的子列和,就更新最大子列和
MaxSum = ThisSum;
else if(ThisSum < 0)//如果当前子列和是负数, 那就不更新
ThisSum = 0;
}
return MaxSum;
}
int main(){
int k, a[MAXN];
cin >> k;
for(int i = 0; i < k; i++){
cin >> a[i];
}
cout << MaxSubseqSum4(a, k) <<endl;
return 0;
}
最大子列和问题的四种时间复杂度解法——来自chenyuelaolao
最新推荐文章于 2020-12-04 10:27:40 发布