最大子段和 - 题解

最大子段和

时间限制:C/C++ 1000MS,其他语言 2000MS
内存限制:C/C++ 128MB,其他语言 256MB

描述

给出一个长度为 \(n\) 的序列 \(a\),选出其中连续且非空的一段使得这段和最大。

输入描述

第一行是一个整数,表示序列的长度 \(n\)
第二行有 \(n\) 个整数,第 \(i\) 个整数表示序列的第 \(i\) 个数字 \(a_i\)
\(1≤n≤2×10^5\)\(−10^4≤a_i≤10^4\)

输出描述

输出一行一个整数表示答案。

用例输入 1

7
2 -4 3 -1 2 -4 3

用例输出 1

4

提示

【样例解释】

选取 \([3,5]\) 子段 \(3,−1,2\), 其和为 \(4\)

代码

贪心 做法

#include<cstdio>
#include<algorithm>
using namespace std;

inline int read()
{
	int x=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<3)+(x<<1)+(ch^'0');
		ch=getchar();
	}
	return x*w;
}

const int N=2e5+5,INF=0x3f3f3f3f;
int n,a[N],f[N];

int main()
{
	n=read();
	for(int i=1;i<=n;i++)
		a[i]=read();
	for(int i=1;i<=n;i++)
		f[i]=max(a[i],f[i-1]+a[i]);
	int ans=-INF;
	for(int i=1;i<=n;i++)
		ans=max(ans,f[i]);
	printf("%d\n",ans);
	return 0;
}

类线段树 做法

#include<cstdio>
#include<algorithm>
using namespace std;

inline int read()
{
	int x=0,w=1;char ch=getchar();
	while(ch<'0'||ch>'9')
	{
		if(ch=='-') w=-1;
		ch=getchar();
	}
	while(ch>='0'&&ch<='9')
	{
		x=(x<<3)+(x<<1)+(ch^'0');
		ch=getchar();
	}
	return x*w;
}

const int N=2e5+5;
int n,a[N];
struct RANGE{
	int l,r;
	int sum;
	int dat,ldat,rdat;
	void build(int il,int ir,int isumdat)
	{
		l=il,r=ir, sum=dat=ldat=rdat=isumdat;
		return;
	}
	void build(int il,int ir,int isum,int idat,int ildat,int irdat)
	{
		l=il,r=ir, sum=isum, dat=idat,ldat=ildat,rdat=irdat;
		return;
	}
};
RANGE rg[N<<2];

void div_conq(int p,int l,int r)
{
	if(l==r)
	{
		rg[p].build(l,r,a[l]);
		return;
	}
	int mid=(l+r)>>1;
	div_conq(p<<1,l,mid), div_conq((p<<1)+1,mid+1,r);
	rg[p].build(
		l,r,
		rg[p<<1].sum+rg[(p<<1)+1].sum,
		max(
			max(
				rg[p<<1].dat,
				rg[(p<<1)+1].dat
			),
			rg[p<<1].rdat+rg[(p<<1)+1].ldat
		),
		max(
			rg[p<<1].ldat,
			rg[p<<1].sum+rg[(p<<1)+1].ldat
		),
		max(
			rg[(p<<1)+1].rdat,
			rg[p<<1].rdat+rg[(p<<1)+1].sum
		)
	);
	return;
}

int main()
{
	n=read();
	for(int i=1;i<=n;i++)
		a[i]=read();
	div_conq(1,1,n);
	printf("%d\n",rg[1].dat);
	return 0;
}
posted @ 2024-07-29 23:30  Jerrycyx  阅读(15)  评论(0编辑  收藏  举报