算法第二章上机实践报告
(1)实践题目:
最长子列和
(2)题目描述:
给定K个整数组成的序列{ N1, N2, ..., NK },“连续子列”被定义为{ Ni, Ni+1, ..., Nj },其中 1。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列
{ -2, 11, -4,13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。
本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:
- 数据1:与样例等价,测试基本正确性;
- 数据2:102个随机整数;
- 数据3:103个随机整数;
- 数据4:104个随机整数;
- 数据5:105个随机整数;
(3)算法描述:
利用递归先将各个区间的数分开直到只剩一个数,然后将区间左边最大连续字段和,右边最大连续子列和以及中间连续最大进行比较,取三者的最大值,然后依次
递归返回,进而求出这个数组的最大子列和。、
代码如下:
1 #include<iostream> 2 3 using namespace std; 4 5 const int N = 1e5 + 10; 6 int q[N]; 7 8 int maxThree ( int A , int B , int C ) 9 { 10 return max( A , max( B , C ) ); 11 } 12 13 int devide( int q[] , int l , int r ) 14 { 15 if( l == r ) 16 { 17 if( q[ l ] >= 0 ) return q[l]; 18 else return 0; 19 } 20 21 int mid = l + r >> 1; 22 int lmax = 0 , rmax = 0; 23 24 lmax = devide( q , l , mid ); 25 rmax = devide( q , mid + 1 , r ); 26 27 int maxLbordersum = 0 , lbordersum = 0; 28 29 for( int i = mid ; i>= l ; i-- ) 30 { 31 lbordersum += q[i]; 32 if( maxLbordersum < lbordersum ) 33 maxLbordersum = lbordersum; 34 } 35 36 int maxRbordersum = 0 , rbordersum = 0; 37 38 for( int i = mid + 1 ; i <= r ; i ++ ) 39 { 40 rbordersum += q[i]; 41 if( maxRbordersum < rbordersum ) 42 maxRbordersum = rbordersum; 43 } 44 45 return maxThree( lmax , rmax , maxRbordersum + maxLbordersum ); 46 } 47 48 int main() 49 { 50 int n; 51 52 cin>>n; 53 54 for( int i= 0; i< n ; i++ ) scanf( "%d" , &q[i] ); 55 56 cout<<devide( q , 0 , n-1 ) <<endl; 57 }
(4)算法时间及空间复杂度分析
首先使用递归算法,每次从中间切开数组,因此一共递归了logn次,而在每一次递归中,要进行对区间处理数据,而处理的时间复杂度为O(n),因此时间复杂度为O(nlogn)。
(5)心得体会
了解并深入学习了递归算法,在编写递归条件是第一句语句应该是写递归的返回条件;其次是深入了解递归的属性,每当可以把问题拆分成小问题,小问题可以拆分成大问题
时,既可以掉用递归算法。