一、实践题目:7-2 最大子段和
二、问题描述:
给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。
要求算法的时间复杂度为O(n)。
三、算法描述:
比较第i个数的前一子段和加上第i个数的总和与第i个数自身的大小,结果存入sum[i]中。
sum[i]表示在由第1~i个字符组成的子段中,含第i个数的最大子段和。
msum则表示由第1~i个字符组成的子段中的最大子段和。
#include <iostream> using namespace std; #define N 10000int nums[N]; int sum[N];int maxSum(int n){sum[1]=nums[1];int msum=sum[1];for(int i=2;i<=n;i++){sum[i]=max(sum[i-1]+nums[i],nums[i]);msum=max(msum,sum[i]);}return msum; }int main(){int n;cin>>n;bool flag=false;for(int i=1;i<=n;i++){cin>>nums[i];if(nums[i]>=0) flag=true;}if(flag==false) cout<<"0";else cout<<maxSum(n);return 0; }
四、算法复杂度分析
1.时间复杂度:对于字符串中的每个字符都进行2次比较,所以大致上,该算法的时间复杂度T(n) = O(n).
2.空间复杂度:在该算法中,为算每个子段的最大子段和,我们增加了sum[]和msum这些辅助变量,所以该算法的空间复杂度也为O(n).
五、心得体会
这次的三道实践题都是具有一定难度的,但实际上都是使用动态规划的解题方法,同时这些题都是可以通过对已学方法的代码进行一些修改而求解的,所以我们要在熟悉了解已学代码的基础上学会变通。