蓝桥杯 算法提高 和最大子序列



  算法提高 和最大子序列  
时间限制:1.0s   内存限制:512.0MB
    
问题描述
  对于一个给定的长度为N的整数序列A,它的“子序列”的定义是:A中非空的一段连续的元素(整数)。你要完成的任务是,在所有可能的子序列中,找到一个子序列,该子序列中所有元素的和是最大的(跟其他所有子序列相比)。程序要求你输出这个最大值。
输入格式
  输入文件的第一行包含一个整数N,第二行包含N个整数,表示A。
  其中
  1 <= N <= 100000
  -10000 <= A[i] <=  10000
输出格式
  输出仅包含一个整数,表示你算出的答案。
样例输入
5
3 -2 3 -5 4


样例输出


4

和最大子序列有四种方法

最笨的方法 3重 循环,这种方法绝对超时。

int MaxSubseqSum1(int A[],int N)
{
	int ThisSum,MaxSum = 0;
	int i,j,k;
	for(i=0;iMaxSum)
			{
				MaxSum = ThisSum;
			}
		}
	}
	//算法复杂度 n的3次方 
	return MaxSum;
}

稍微改进了一点点 的 方法,二重循环

int MaxSubseqSum2(int A[],int N)
{
	int ThisSum,MaxSum = 0;
	int i,j,k;
	for(i=0;iMaxSum)
			{
				MaxSum = ThisSum;
			}
		}
	}
	
	return MaxSum;
}

第三种,分而治之 法 算法复杂度(O(nlogN)),目前我还不理解 。 哈哈哈哈

int Max3( int A, int B, int C ) 
{     
	return A > B ? A > C ? A : C : B > C ? B : C; /* 返回3个整数中的最大值 */ 
} 
int DivideAndConquer( int List[], int left, int right )
{ 					/* 分治法求List[left]到List[right]的最大子列和 */     
	int MaxLeftSum, MaxRightSum; 
						/* 存放左右子问题的解 */     
	int MaxLeftBorderSum, MaxRightBorderSum; 
						/*存放跨分界线的结果*/     
	int LeftBorderSum, RightBorderSum;
     	int center, i;     
	if( left == right )  
	{ 					/* 递归的终止条件,子列只有1个数字 */         
		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 )
{ /* 保持与前2种算法相同的函数接口 */
	return DivideAndConquer( List, 0, N-1 );
}

第四种, 最优算法, 复杂度O(n) 

#include 
using namespace std;
int main()
{
	int N,t;
	cin>>N;
	int ThisSum = 0;
	int MaxSum = 0;
	for(int i=0;i> t;
		ThisSum += t;
		if(ThisSum > MaxSum)
		{
			MaxSum =ThisSum;
		}
		else if(ThisSum<0)
		{
			ThisSum = 0;
		}
	}
	cout<
简直完美!!! 数组都不要用了,节省空间和时间。可惜有很大的局限性。

你可能感兴趣的:(蓝桥杯)