瞬间求解最大连续和

已知一组整数数据 A1,A2,A3,A4,A5,A6.....AN ,并返回最大连续和。

先给出最极品的算法:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
const int maxn=10000;

int A[maxn],S[maxn];
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
	int n;
	scanf("%d",&n);
	int i;
	for(i=0;i<n;i++) scanf("%d",&A[i]);
	S[0]=A[0];
	//printf("S[0]=%d\n",S[0]);
	int best=A[0],tot=0;
	for(i=1;i<n;i++) //计算前缀和 
	{
		tot++;
		S[i]=S[i-1]+A[i];
	}
	int min_S=0;//保存当前遇到的最小S,当min_S=S[0]或其他的,都不对。 
	for(int j=1;j<n;j++)
	{
		best>?=S[j]-min_S;//A[i]+……+A[j]=S[j]-S[i-1],当j确定时,减去之前遇到的最小s即可 
		min_S<?=S[j];//维护最小的s 
	}
	printf("min_S=%d\n",min_S);
  	printf("n=%d tot=%d\n",n,tot);
  	printf("%d\n",best);
    return 0;
}

剩下的由高效到低效排序如下:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
const int maxn=10000;

int A[maxn],tot;

int maxsum(int *A,int x,int y)//在[x,y)左闭右开区间中求最大连续和 
{
	if(y-x==1) return A[x];//没有这句不行,递归程序会一直运行下去。写递归函数,注意递归边界。 
	int m=x+(y-x)/2;//求靠近0的中点 
	int max=maxsum(A,x,m)>?maxsum(A,m,y);//求解子问题 
	int i,v,L,R;
	L=A[m-1];v=0;
	for(i=m-1;i>=x;i--) L>?= v+=A[i];//由划分处向左边求最大连续和 
	tot+=(m-x);// 记录加法操作数目 
	R=A[m];v=0;
	for(i=m;i<y;i++) R>?= v+=A[i];//由划分处向右边求最大连续和  
	tot+=(y-m);
	return max>?L+R;//合并问题 
}

int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
	int n;
	scanf("%d",&n);
	int i;
	for(i=0;i<n;i++) scanf("%d",&A[i]);
	tot=0;
	int best=maxsum(A,0,n);//直接调用求解[0,n)的最大连续和 
  	printf("n=%d tot=%d\n",n,tot);
  	printf("%d\n",best);
    return 0;
}

O(n2):

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
const int maxn=10000;

int A[maxn],S[maxn];
int main()
{
#ifndef ONLINE_JUDGE
    freopen("in.txt","r",stdin);
#endif
	int n;
	scanf("%d",&n);
	int i;
	for(i=0;i<n;i++) scanf("%d",&A[i]);
	S[0]=A[0];
	int best=A[0],tot=0;
	for(i=1;i<n;i++) 
	{
		tot++;
		S[i]=S[i-1]+A[i];
	}
	for(i=0;i<n;i++)
	  for(int j=i;j<n;j++) 
	  {
 		 tot++;
  		 best>?=S[j]-S[i-1];
  	}
  	printf("n=%d tot=%d\n",n,tot);
  	printf("%d\n",best);
    return 0;
}

O(n*n*n):

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<time.h>
const int maxn=30;

int A[maxn];
int main()
{
#ifndef ONLINE_JUDGE
    //freopen("in.txt","r",stdin);
#endif
	int n;
	scanf("%d",&n);
	int i;
	for(i=0;i<n;i++) scanf("%d",&A[i]);
	int best=A[0],tot=0;
	for(i=0;i<n;i++)
	  for(int j=i;j<n;j++)
	  {
	  	 int sum=0;
  		 for(int k=i;k<=j;k++) 
  		 {
 		  	sum+=A[k];
 		  	tot++;
	  	 }
  		 best>?=sum;
  	}
  	printf("n=%d tot=%d\n",n,tot);
  	printf("%d\n",best);
  	printf("Time used=%.2lf\n",(double)clock()/CLOCKS_PER_SEC);	
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值