雪中拥抱你

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

一、实验题目

7-1 最大子段和 (25 分)

给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。

要求算法的时间复杂度为O(n)。

输入格式:

输入有两行:

第一行是n值(1<=n<=10000);

第二行是n个整数。

输出格式:

输出最大子段和。

输入样例:

在这里给出一组输入。例如:

6
-2 11 -4 13 -5 -2
 结尾无空行

输出样例:

在这里给出相应的输出。例如:20

 

二、算法描述

题目要求最大子段和,则我们需要一个额外的记录数组d[n],并先将其初始化成与原数组x[n]一致,即d[n]=x[n],d[n]表示到第n个数值的最大子段和。再根据动态规划由底到顶的方式,从第n-1个数值开始循环(如果从第n个开始,则不会受前一个数值的影响而改变d[n]的值,直接等于x[n]里第n个数值)若d[i+1]大于0,则证明d[i+1]的数值会影响d[i],需要加上,则得出递推式d[i]=x[i]+d[i+1];若d[i+1]小于0,则证明d[i+1]的数值不会影响d[i],则记录数组d[i]与原数组x[i]一致。

三、我的代码

#include<iostream>
using namespace std;
int main(){
int n,max=0;     //题目要求当所给的整数均为负数时,定义子段和为0,则可以先初始化max=0
cin>>n;
int x[n];
int d[n];
for(int i=1;i<=n;i++){
cin>>x[i];
d[i]=x[i];
}
for(int i=n-1;i>=1;i--){
if(d[i+1]>0)d[i]=x[i]+d[i+1];
else d[i]=x[i];
if(d[i]>max)max=d[i];
}
cout<<max;
return 0;
}

 四、复杂度

只有一个循环,时间复杂度为O(n)。

空间复杂度为O(n)

 

五、心得体会

动态规划是真的很难,有好多东西要注意的一不留神就会错(比如什么边界条件之类的),最最关键的递推关键式的得出是建立在对题目的理解上,要通过草稿纸上的推算和独立的思考。

 
posted on 2021-10-26 22:33  雪中拥抱你  阅读(40)  评论(0编辑  收藏  举报