题目链接:最大连续子序列
思路分析:
最暴力的自然是三层循环了,自然是TLE,我用的sum[i]来储存前i项的和(感觉有点前缀和的思想),时间复杂度到了O(n^2),还是超时了。我想过既然是一维数组,应该遍历一遍就行的,可是依然没有想到解决的方法,直到看题解,我又怀疑我的智商了,这么简单就是想不到。我们用sum[i]来储存以a[i]为末尾的子序列的最大和,有sum[i]=max(sum[i-1]+a[i],a[i])。至于寻找序列的左端点和右端点直接看代码把。
#include <cstdio>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <vector>
#include <queue>
using namespace std;
const int inf=0x3f3f3f3f;
int sum[10001],a[10001];
int main()
{
int n,i,flag,maxer,p,r,l;
while(cin>>n && n)
{
flag=0;
maxer=-inf;
sum[0]=0;
for(i=1;i<=n;i++)
{
cin>>a[i];
if(a[i]>=0)
flag=1;
}
if(!flag)
printf("0 %d %d\n",a[1],a[n]);
else
{
r=1,p=1;
for(i=1;i<=n;i++)
{
sum[i]=max(sum[i-1]+a[i],a[i]);
if(sum[i-1]<0) //如果sum[i-1]<0,显然sum[i]=a[i],我们就把p设为i,但仅仅是用p储存一下,至于这个值究竟是不是最终的左下标,还要看sum[i]是否大于maxer.
p=i;
if(sum[i]>maxer)
{
maxer=sum[i];
l=p;
r=i;
}
}
cout<<maxer<<' '<<a[l]<<' '<<a[r]<<endl;
}
}
}