#数据结构与算法学习笔记#PTA4:分治算法求最大子列和(C/C++)

2018.3.17

// MaxSubsequence2.cpp : 定义控制台应用程序的入口点。
// 分治算法求最大子列和
// 基本思想为二分分治并递归求解左子列最大和、右子列最大和、跨中线子列最大和,比较求出最大和。

//“最大子列和”则被定义为所有连续子列元素的和中最大者。
//例如给定序列{ -2, 11, -4, 13, -5, -2 },其连续子列{ 11, -4, 13 }有最大的和20。
//Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.

#include "stdafx.h"
#include <stdlib.h>
#include <stdio.h>


#define MAX 100000
int MaxSubseq(int n, int data[]);
void Read(int n, int data[]);
int Max3(int A, int B, int C);
int DivideAndConquer(int data[], int left, int right);




int main()
{
	int n;
	scanf("%d", &n);
	int data[MAX];
	Read(n, data);

	int result;
	result = MaxSubseq(n, data);
	if (result < 0)result = 0;
	printf("%d", result);
	return 0;
}


void Read(int n, int data[]) {
	int value;
	for (int i = 0;i < n;i++) {
		scanf("%d", &value);
		data[i] = value;
	}
}

//求三数最大值
int Max3(int A, int B, int C)
{ 
	return (A > B ? (A > C ? A : C ): (B > C ? B : C));
}

//分治算法求最大子列和,复杂度NlogN
int DivideAndConquer(int data[], int left, int right)
{
	//递归终止条件
	if (left == right) {
		if (data[left] > 0)return data[left];
		else return 0;
	}

	//递归调用
	int center = (left + right) / 2;
	int maxLeftSum = DivideAndConquer(data, left, center);//左子列最大和
	int maxRightSum = DivideAndConquer(data, center + 1, right);//右子列最大和,注意从center+1开始

	//中线向左扫描
	int maxLeftBorderSum = 0, leftBorderSum = 0;
	for (int i = center;i >= left;i--) {
		leftBorderSum += data[i];
		if (leftBorderSum > maxLeftBorderSum) {
			maxLeftBorderSum = leftBorderSum;
		}
	}

	//中线向右扫描
	int maxRightBorderSum = 0, rightBorderSum = 0;
	for (int i = center+1;i <=right;i++) {
		rightBorderSum += data[i];
		if (rightBorderSum > maxRightBorderSum) {
			maxRightBorderSum = rightBorderSum;
		}
	}

	int maxBorderSum = Max3(maxLeftSum, maxRightSum, maxLeftBorderSum+ maxRightBorderSum);	//跨边界最大子列和
	return maxBorderSum;
}

int MaxSubseq(int n, int data[]) {
	return DivideAndConquer(data, 0, n - 1);
}


猜你喜欢

转载自blog.csdn.net/qq_20304723/article/details/79593815