2018.3.17
分治算法求最大子列和
基本思想为二分分治并递归求解左子列最大和、右子列最大和、跨中线子列最大和,比较求出最大和。
“最大子列和”则被定义为所有连续子列元素的和中最大者。
例如给定序列{ -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.
基本思想为二分分治并递归求解左子列最大和、右子列最大和、跨中线子列最大和,比较求出最大和。
// 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
#include
#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);
}
#Coding一小时,Copying一秒钟。留个言点个赞呗,谢谢你#