第三次作业

---恢复内容开始---

因为感觉都比较难,所以果断选第一个题目 # 问题: 给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时定义子段和为0,依此定义,所求的最优值为: Max{0,a[i]+a[i+1]+…+a[j]},1<=i<=j<=n 例如,当(a[1],a[2],a[3],a[4],a[5],a[6])=(-2,11,-4,13,-5,-2)时,最大子段和为20。 ## 一,算法 描述:针对最大子段和这个具体问题本身的结构,我们还可以从算法设计的策略上对上述O(n^2)计算时间算法进行更进一步的改进。从问题的解结构也可以看出,它适合于用分治法求解。 如果将所给的序列a[1:n]分为长度相等的两段a[1:n/2]和a[n/2+1:n],分别求出这两段的最大子段和,则a[1:n]的最大子段和有三种情况: (1) a[1:n]的最大子段和与a[1:n/2]的最大子段和相同 (2) a[1:n]的最大子段和与a[n/2+1:n]的最大子段和相同 (3) a[1:n]的最大子段和为a[i]+…+a[j],并且1<=i<=n/2,n/2+1<=j<=n。 对于(1)和(2)两种情况可递归求得,但是对于情况(3),容易看出a[n/2],a[n/2+1]在最大子段中。因此,我们可以在a[1:n/2]中计算出s1=max(a[n/2]+a[n/2-1]+…+a[i]),0<=i<=n/2,并在a[n/2+1:n]中计算出s2= max(a[n/2+1]+a[n/2+2]+…+a[i]),n/2+1<=i<=n。则s1+s2为出现情况(3)的最大子段和。 ## 二,关键代码 #include using namespace std; int b[100][100]; int main() { int a[100]; int n,k; cin>>n; for(k=0;k>a[k]; int i,j; for(i=0;imax) max=b[s][B]; cout<---恢复内容结束---

posted @ 2018-04-01 19:58  深渊巨坑小黑  阅读(123)  评论(0编辑  收藏  举报