竞赛篇-----最大连续和问题

1)首先最简单的就是模拟时间复杂度是O(n^3)

/*
最大连续和问题
O(n^3)
*/
#include<cstdio>
#include<iostream>
using namespace std;
int main() {
	int a[1005],n,sum,ans;
	while(~scanf("%d",&n)) {
		for(int i=1; i<=n; i++)
			scanf("%d",&a[i]);
		ans=a[1];
		int cnt=0;
		for(int i=1; i<=n; i++)
			for(int j=i; j<=n; j++) {
				sum=0;
				for(int k=i; k<=j; k++)					
				{
					sum+=a[k];
					cnt++;
				} 
				ans=max(ans,sum);
			}
		printf("ans=%d cnt=%d\n",ans,cnt);
	}
}

2)将上述的代码优化一点点,运用树状数组的思想求子序列的和为两个前缀和之差

        时间复杂度为O(n^2)相对于上面的3次方的时间复杂度优化了不少。

/*
最大连续和,运用:子序列和等于两个前缀和之差
O(n^2) 
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int main() {
	int a[1005],ans,n,s[1005];
	while(~scanf("%d",&n)) {
		for(int i=1; i<=n; i++)
			scanf("%d",&a[i]);
		s[0]=0;
		ans=a[1];
		for(int i=1; i<=n; i++)
			s[i]=s[i-1]+a[i];
		for(int i=1; i<=n; i++)
			for(int j=i; j<=n; j++)
				ans=max(ans,s[j]-s[i-1]);
		printf("%d\n",ans);
	}
}

3)接下来还可以将2次方是时间复杂度再次优化,那就是用分治法。

         时间复杂度为O(nlogn),相比较而言又优化了很多

/*
分治法求最大连续和问题
分治法的三个步骤:
1)划分问题:把问题的实例化成子问题
2)递归求解:递归解决子问题
3)合并问题:合并子问题的解,得到原问题的解
O(nlogn)
*/
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
int a[1005];
int maxsum(int *a,int x,int y) { //返回在数组中左闭右开[x,y)的最大连续和(空区间可表示为[x,x))
	int v,l,r,maxs;
	if(y-x==1) return a[x];//如果只有一个元素,直接返回;
	int m=x+(y-x)/2;//第一步,划分成[x,m),[m,y);
	//此处用x+(y-x)/2,而不用(x+y)/2,'/'总是朝0方向取整,而不是向下取整,此处的方式可以保证分界点总是靠近区间起点。
	maxs=max(maxsum(a,x,m),maxsum(a,m,y));//第二步:递归求解子问题
	//第三步:合并;
	v=0,l=a[m-1];//从分界点开始往左的最大连续和l;
	for(int i=m-1; i>=x; i--)
		l=max(l,v+=a[i]);
	v=0,r=a[m];//从分界点开始往右的最大连续和r;
	for(int i=m; i<y; i++)
		r=max(r,v+=a[i]);
	return max(maxs,l+r);
}
int main() {
	int n;
	while(~scanf("%d",&n)) {
		for(int i=1; i<=n; i++)
			scanf("%d",&a[i]);
		printf("%d\n",maxsum(a,1,n+1));
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值