PAT数据结构_01-复杂度1 最大子列和问题

题目:https://pta.patest.cn/pta/test/15/exam/4/question/709



#include <iostream>
using namespace std;

int MaxSubseqSum2(int A[], int N);
int MaxSubseqSum3(int A[], int left, int right);		//(数组名,元素左起0,元素终点n-1)
int MaxSubseqSum4(int A[], int N);			//(数组名, 元素个数)


int main()
{
	int n;
	cin >> n;
	// int numSeq[n];				//C++是不支持用变量初始化数组的
	int numSeq[100000];

	for(int i=0; i<n; i++){
		cin >> numSeq[i];
	}

	// int maxSum = MaxSubseqSum4(numSeq, n);
	int maxSum = MaxSubseqSum3(numSeq, 0, n-1);
	if(maxSum< 0) {
		maxSum = 0;
	}
	cout<<maxSum<<endl;

	return 0;
}


// 算法2  穷举法
int MaxSubseqSum2(int A[], int N){	
	int ThisSum, MaxSum = 0;
	int i, j, k;
	for(i=0; i<N; i++){						//i是子列左端位置
		ThisSum = 0;						//ThisSum是从A[i]到A[j]的子列和
		for(j=i; j<N; j++){					//j是子列右端位置
			ThisSum += A[j];
			//对于相同的i,不同的j,只要在j-1次循环的基础上累加1项即可
			if(ThisSum > MaxSum)			//如果刚得到的这个子列和更大
				MaxSum = ThisSum;			//则更新结果
		}	//j循环结束
	}	//i循环结束
	return MaxSum;
}

int compareThreeNums(int a, int b, int c){
	return a>b ? (a>c?a:c) : (b>c?b:c)  ;		//if a>b: then if a>c, else if b>c
}
// 算法3  分而治之
int MaxSubseqSum3(int A[], int left, int right){
	int leftMax, rightMax;

	//如果list中只剩一个元素了,则left==right
	if(left == right){
		return A[left];
	}
	//list不只一个元素,二分+治之 递归,获得左右最大
	int middle = (left + right) / 2;
	leftMax = MaxSubseqSum3(A, left, middle);
	rightMax = MaxSubseqSum3(A, middle+1, right);
	
	//寻找跨越边界的最大
	// int tempLeftMax, leftBorderMax = 0;						//未显式赋值,造成错误假内容
	// int tempRightMax, rightBorderMax = 0;
	int tempLeftMax = 0, leftBorderMax = 0;				
	for (int i = middle; i >= left; i--){
		tempLeftMax += A[i];
		if(tempLeftMax > leftBorderMax){
			leftBorderMax = tempLeftMax;	
		}
	}
	int tempRightMax = 0, rightBorderMax = 0;
	for (int i = middle+1; i <= right; i++){
		tempRightMax += A[i];
		if(tempRightMax > rightBorderMax){
			rightBorderMax = tempRightMax;	
		}
	}
	int middleMax = rightBorderMax + leftBorderMax;

	int maxSum = compareThreeNums(middleMax, leftMax, rightMax);
	return maxSum;
}

// 算法4  在线方法/动态规划  
int MaxSubseqSum4(int A[], int N){
	int maxSum, thisSum = 0;
	int i = 0;
	for(i = 0; i<N; i++){
		thisSum += A[i];					/* 向右累加 */
		if(thisSum > maxSum){
			maxSum = thisSum;				/* 发现更大和则更新当前结果 */ 
		} else if (thisSum < 0){			/* 如果当前子列和为负 */
			thisSum = 0;					/* 则不可能使后面的部分和增大,抛弃之 */
		}									
	}
	//此题里,不需要记录最大和的具体项,发现新最大立刻更新,当前和已经小于0时,则加后面的大项必然可以大过加已有的负数
	return maxSum;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值