算法第3章上机实践报告
1.实践题目
最大子段和
2.问题描述
给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。
要求算法的时间复杂度为O(n)。
3.算法描述
最大子段和也是动态规划的一个典型问题,它比较不一样的点在于它两端都是变化的。此时应该固定一端简化问题。若记b[j]=max(a[i]+a[i+1]+..+a[j]),其中1<=i<=j,并且1<=j<=n。则所求的最大子段和为max b[j],1<=j<=n。
由b[j]的定义可易知,当b[j-1]>0时b[j]=b[j-1]+a[j],否则b[j]=a[j]。故b[j]的动态规划递归式为:
b[j]=max(b[j-1]+a[j],a[j]),1<=j<=n。
代码如下:
#include <iostream> using namespace std; int main(){ int n; cin>>n; int a[n]; int b[n]; int max; for(int i = 0;i<n;i++){ cin>>a[i]; } b[0]=a[0]; max=b[0]; for(int i = 1;i<n ; i++){ if(b[i-1]>0){ b[i]=b[i-1]+a[i]; } else b[i]=a[i]; if(max<b[i]){ max=b[i]; } } if(max>0) cout<<max; else cout<<"0"; return 0; }
4.算法时间及空间复杂度分析
代码中用到了一重for循环,其余均为常数量级,所以时间复杂度为
T=O(n)
空间复杂度为O(1)
5.心得体会
这是一道典型的动态规划问题,在结对编程的过程中一开始遇到了瓶颈,不知道在两端都变化的情况下如何找到确定其最优解。解决这一问题后,与其他动态规划问题找到了相同的思路,解决了这道问题。具体情况具体分析 看决策和转移,选择。