最大连续整数和

#include "stdio.h"
#define MAX 1000
int A[MAX];
int main () {
	int i;
	int j;
	int k;
	int maxmum;
	int sum;
	for (i = 1;i <= MAX;i++) {
		A[i] = i;
	}
	maxmum = A[1];
	for (i = 1;i <= MAX;i++) {
		for (j = i;j <= MAX;j++) {
			sum = 0;
			for (k = i;k <= j;k++) {
				sum = sum + A[k];
			}
			if (maxmum < sum) {
				maxmum = sum;
			}
		}
	}
	printf ("%d\n",maxmum);
	return 0;
}
>
//使用S(i) = A[1] + A[2] + A[3] +.......+A[i], S[j] = A[1] + A[2] +.....+A[j],S(j) - S(i-1) = A[i] + A[i+1] +...+ A[j];
#include "stdio.h"
#define MAX 1000
int A[MAX];
int S[MAX];
int main () {
	int i;
	int j;
	int k;
	int maxmum;
	for (i = 1;i <=MAX;i++) {
		A[i] = i;
	}
	S[0] = 0;
	for (i = 1;i <= MAX;i++) {
		S[i] = S[i-1] + A[i];
	}
	maxmum = A[1];
	for (i = 1;i <= MAX;i++) {
		for (j = i;j <= MAX;j++) {
			int sum = S[j] - S[i-1];
			if (maxmum < sum) {
				maxmum = sum;
			}
		}
	}
	printf ("%d\n",maxmum);
	return 0;
}

时间复杂度从O(n^3)降到O(n^2)

用分治法解决这个问题,渐近时间复杂度为O(nlgn)
分治法一般三个步骤为:
1:划分问题:把问题的实例划分成子问题。
2:递归求解:递归解决子问题。
3:合并问题:合并子问题的解得到原问题的解。
#include "stdio.h"
/**
 *递归方程T(n) = 2T( n / 2) + O(n),T(1) = 1的解为O(nlogn)
 */
int maxsum (int *A,int x,int y) {
	int z;
	int max;
	int tmp;
	int i,l,r,v;
	if (y - x == 1){
		return A[x];
	}
	z = x + (y - x) / 2;//分治法第一步:划分为[x,z)和[z,y) 注:左闭右开
	max = maxsum (A,x,z);
	tmp = maxsum (A,z,y);//分治法第二步:递归求解
	max = max < tmp ? tmp:max;
	//合并子问题。整个过程可以使用解答树来描述。
	l = A[z - 1];
	v = 0;
	for (i = z-1;i >= x;i--) {
		v = v + A[i];
		if (l < v) l = v; 
	}
	v = 0;
	r = A[z];
	for (i = z;i < y;i++){
		v = v + A[i];
		if (r < v){
			r = v;
		}
	}
	if (max < r + l) {
		max = r+l;
	}
	return max;
}
#define MAX 10000
int A[MAX];
int main () {
	int i;
	for (i = 0;i < MAX;i++){
		A[i] = i + 1;
	}
	int max = maxsum (A,0,MAX);
	printf ("%d\n",max);
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值