1.实践题目
7-2最大子段和 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。
要求算法的时间复杂度为O(n)。
2.问题描述
输入格式:
输入有两行:
第一行是n值(1<=n<=10000);
第二行是n个整数。
输出格式:
输出最大子段和。
输入样例:
在这里给出一组输入。例如:
6
-2 11 -4 13 -5 -2
输出样例:
在这里给出相应的输出。例如:
20
3.算法描述
经过讨论,我们小组决定采用的是动态规划的解法来解决这一个题目,我们创建了一个数组来存放从初始位置到各位的最大子段和,通过比较最大子段和得出的两种方式,取其大者,并将这个最大子段和与目前的最大子段和比较,记录下最大的,最终得出整段数列的最大子段和。
4.算法时间及空间复杂度分析
时间复杂度:由于代码中没有二重循环,至多只要一重循环,所以这个算法的时间复杂度是O(N)级别的。
空间复杂度:
5.心得体会(对本次实践收获及疑惑进行总结)
对于动态规划类的题目,做法比较明确,但是难点是写出递归表达式,这个十分考验做题者的思维能力,还需要在不断做题才能一步一步提升,不然还是没办法做好这俩算法题。
ps:附上代码
#include<iostream>
using namespace std;
int main(){
int n,maxn;
int a[10005];
int b[10005];
cin>>n;
if(n<0||n>10000)return 0;
for (int i=1;i<=n;i++)
cin>>a[i];
maxn=b[1]=a[1];
for(int j=1;j<=n;j++){
if (maxn<0) maxn=b[j]=0;
b[j+1]=b[j]+a[j+1];
if(b[j+1]<0) {
j++;
b[j+1]=a[j+1];
}
maxn=max(maxn,b[j+1]);
}
cout<<maxn;
return 0;
}
原文地址:https://www.cnblogs.com/lhiscute/p/9940448.html