算法第二章上机实践报告
#include<iostream> using namespace std; int maxsum(int a[],int l,int r) { int sum=0; if(l==r) { sum=a[l]>0?a[l]:0;//如果只有一个数,小于零就置为零,反之则输出它本身 } else{ int mid = (l+r)/2; int lsum=maxsum(a,l,mid); int rsum=maxsum(a,mid+1,r); int s1=0; int lefts=0; for(int i=mid;i>=l;i--) { lefts+=a[i]; if(lefts >s1) { s1=lefts; } } int s2=0; int rights=0; for(int i=mid+1;i<=r;i++) { rights+=a[i]; if(rights>s2) { s2=rights; } } sum=s2+s1; if(sum<lsum) { sum=lsum; } if(sum<rsum) { sum=rsum; } return sum; } } int MaxSum(int n,int *a) { return maxsum(a,1,n); } int main() { int K,a[200005]; cin>>K; for(int i=1;i<=K;i++) { cin>>a[i]; } cout<<MaxSum(K,a); return 0; }
以求最大子列和为例
一,实践题目名称:最大子列和问题
二,问题描述:
给定K个整数组成的序列{ N1 , N2 , ..., NK },“连续子列”被定义为{ Ni, Ni+1 , ..., Nj
},其中 1≤i≤j≤K。“最大子列和”则被定义为所有连续子列元素的和中最大者。例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。现要求你编写程序,计算给定整数序列的最大子列和。
本题旨在测试各种不同的算法在各种数据情况下的表现。各组测试数据特点如下:
数据1:与样例等价,测试基本正确性;
数据2:102个随机整数;
数据3:103个随机整数;
数据4:104个随机整数;
数据5:105个随机整数;
三,算法描述:
把数组分两半,求出左边最大子段和,右边最大子段和,以及跨两边的最大子段和,三者比较,选出最大的即可。
四,算法时间复杂度和空间复杂度分析
时间复杂度:假设问题规模为n问题被划分为两个子问题,2T(N/2);合并子问题,o(N), 所以 T(N)=2T(N/2)+o(N),则时间复杂度为o(nlogn)
空间复杂度:老师,我不会分析...
五,心得体会
对分治法思想的理解更加深入,运用更加熟练。相比最暴力最传统的方法(所有字段和都求出来),分治法避免了重复的计算,提高了效率。
实验课那天,按照书上的代码敲出来,代码通过了,以为自己懂了,但其实当老师提问时,又回答不清晰。
只有自己理解了才可以真正的掌握知识。