算法第二章上机实践报告

(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)心得体会

  了解并深入学习了递归算法,在编写递归条件是第一句语句应该是写递归的返回条件;其次是深入了解递归的属性,每当可以把问题拆分成小问题,小问题可以拆分成大问题

,既可以掉用递归算法。

posted @ 2020-10-01 11:42  阿柴啊啊啊·  阅读(127)  评论(0编辑  收藏  举报