算法第3章上机实践报告
一、实践题目: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 10000 int 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).
五、心得体会
这次的三道实践题都是具有一定难度的,但实际上都是使用动态规划的解题方法,同时这些题都是可以通过对已学方法的代码进行一些修改而求解的,所以我们要在熟悉了解已学代码的基础上学会变通。