题目描述
给出一个长度为 nn 的序列 aa,选出其中连续且非空的一段使得这段和最大。
输入格式
第一行是一个整数,表示序列的长度 nn。
第二行有 nn 个整数,第 ii 个整数表示序列的第 ii 个数字 a_iai。
输出格式
输出一行一个整数表示答案。
输入样例
7 2 -4 3 -1 2 -4 3
输出样例
4
这个题我们可以用两个数组进行实现,一个数组代表这个数和后一个数相加的和,另外一个数组代表后一个数,为什么我会用两个数组呢,不急,来我们一起分析:
童鞋们可以在本子上推导一下题中给的案例:
首先是个2,如果我们输入的仅仅只有一个数,那么这个数就是最大值,我们直接输出就完犊,
再想,如果是2后面跟着数字-4,我们将这两个数相加,拿么得到的是-2,哦,我们发现,这两个数如果同时参加这个“聚会”,得到的值还没有一个2大,显然不能成立,依次往后,如果后面来个3,如果我们只取-4和3,相加得-1,呕吼,又帮个倒忙,又变小了。如果还有2也参与,结果则是
2-4+3,童鞋自己算等于多少,咳咳,是不是等于1,偶吼吼,真聪明。
我们发现,数字还没有单个大,那意味着又失败了,被担心,失败是成功之母嘛。
接着,后面有个-1,没意思,只会拉后腿,不要它。往后,2来了,通过观察分析:
2,-1,3他们成了最好的伙伴,相加之后没有比他们更大的,soga,haha,奇迹就此诞生。
所以总结出来:
一个有效数列加上数组中的一个数,如果所得的的结果比这个数大,那么将这个数纳入这个有效家族中
反之,这个数独自称王。
用dp:
b[i]=max(b[i-1]+a[i],a[i])
接下来上代码:
#include<bits/stdc++.h>
using namespace std;
int main()
{
int n,i,s=-9999999,a[210000],b[210000]={0};//a[210000]数组存储数据,b[210000]表示有效数列
cin>>n;
for(i=1;i<=n;i++)
{
cin>>a[i];
b[i]=max(b[i-1]+a[i],a[i]);//将有效数列与数组某个数相加得到的结果与这个数比较,返回最大值
s=max(s,b[i]);//s用来代表负数
}
cout<<s;
return 0;
}
不过这个题时间复杂度是O(n),如果大家有更好的算法,思路,还希望告知小编,可能我在编写时由不足之处,还希望童鞋指出,蟹蟹童鞋men ^ ^