求最大连续和的几种方法

本文内容参考《算法竞赛入门经典第2版》220~223页
Q:给出一个长度为 n n n的序列 A 1 , A 2 , A 3 , ⋯   , A n A_{1},A_{2},A_{3},\cdots,A_{n} A1,A2,A3,,An,求最大连续和。换句话说,要求找到 1 ≤ i ≤ j ≤ n 1\leq i\leq j \leq n 1ijn,使得 A i + A i + 1 + ⋯ + A j A_{i}+A_{i+1}+\cdots+A_{j} Ai+Ai+1++Aj尽量大。
方法一:
暴力枚举,时间复杂度 O ( n 3 ) O(n^{3}) O(n3)

ans=A[1];//所求的最大连续和 
for(int i=1;i<=n;i++){
	for(int j=i;j<=n;j++){//枚举区间[i,j] 
		int sum=0;
		for(int k=i;k<=j;k++){//对区间[i,j]内的所有数求和 
			sum+=A[k];
		}
		ans=max(sum,ans);//取最大值 
	}
}

方法二:
利用前缀和,时间复杂度 O ( n 2 ) O(n^{2}) O(n2)

s[0]=0;
for(int i=1;i<=n;i++){//提前求前缀和(s[i]表示从A[i]数组从1到i的所有数之和),降低时间复杂度 
	s[i]=s[i-1]+A[i];
}
ans=s[0];
for(int i=1;i<=n;i++){
	for(int j=i;j<=n;j++){
		ans=max(ans,s[j]-s[i-1]);
	}
}

方法三:
分治法,时间复杂度 O ( n l o g n ) O(nlogn) O(nlogn)

int maxSum(int*A,int x,int y){//返回数组在左闭右开区间[x,y)中的最大连续和 
	if(y-x==1){
		return A[x];
	}
	int m=x+(y-x)/2;//划分成[x,m)和[m,y) 
	int maxs=max(maxSum(A,x,m),maxSum(A,m,y));
	int v,L,R;
	v=0;
	L=A[m-1];
	for(int i=m-1;i>=x;i--){//从分界点往左的最大连续和 
		L=max(L,v+=A[i]);
	}
	v=0;
	R=A[m];
	for(int i=m;i<y;i++){//从分界点往右的最大连续和 
		R=max(R,v+=A[i]);
	}
	return max(maxs,L+R);//子问题的解与L和R比较 
} 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值