第二章实验报告
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个随机整数;
输入格式
输入第1行给出正整数K (≤);第2行给出K个整数,其间以空格分隔。
输出格式:
在一行中输出最大子列和。如果序列中所有整数皆为负数,则输出0。
输入样例:
6
-2 11 -4 13 -5 -2
输出样例:
20
3.算法时间及空间复杂度分析(要有分析过程)
设算法的复杂度为T(N),
第一步分解为两个子问题为O(1)
第二步分别求解两个子问题为O(N/2)*2
第三步合并子问题为O(N)
等式为:T(N)=O(1)+2T(N/2)+O(N)
得:T(N)=O(nlogn);
4.心得体会(对本次实践收获及疑惑进行总结)
其实是对与递归算法的不熟悉和难以理解,最开始时采用了三重循环的方法写代码,但看到最后一个测试点3000多ms时间的复杂度时,才了解为什么要学习新的算法。虽然至今还是很难理解透彻递归的写法和思维。但我还是会多去模仿,多写几次就明白了
5.代码
#include <iostream>
using namespace std;
int max ( int a, int b, int c )
{
if (a>b)
{
if(b>c)
return a;
else
if(a<c)
return c;
}
else if (c<a)
return b;
}
int xing ( int a[], int left, int right )
{
int maxl, maxr;
int summaxl, summaxr;
int suml, sumr;
int mid, i;
if ( left == right )
{
if ( a[left] > 0 ) return a[left];
else return 0;
}
mid = ( left + right ) / 2; //找到中分点。
maxl = xing ( a, left, mid); //递归求左子列和。
maxr = xing( a, mid+1, right ); //递归求右子列和。
summaxl = 0;suml = 0;
for ( i = mid; i >= left; i– )
{
suml += a[i];
if ( suml > summaxl )
summaxl= suml;
}//左边扫描结束。
summaxr = 0; sumr = 0;
for ( i = mid+1; i <= right; i++ )
{
sumr += a[i];
if ( sumr > summaxr )
summaxr = sumr;
}//右边扫描结束。
/*返回“治”的结果*/
return max (maxl, maxr, summaxl + summaxr );
}
int main ()
{
int n,i;
cin>>n;
int a[n];
int left=0,right=n;
for (i=1;i<=n;i++)
{
cin>>a[i];
}
cout<<xing(a,left,right);
}