#include<stdio.h>
#define maxN 10000
int MaxSubseqSum1(int A[], int N);
int MaxSubseqSum2(int A[], int N);
int Max3(int A, int B, int C);
int DivideAndConquer(int List[], int left, int right);
int MaxSubseqSum3(int List[], int N);
int MaxSubseqSum4(int A[], int N);
int main() {
int a[maxN] = { 0 };
int num = 0;
scanf("%d", &num);
for (int i = 0; i < num; i++)
scanf("%d", &a[i]);
printf("%d", MaxSubseqSum1(a, num));
return 0;
}
// 复杂度是n的三次方
int MaxSubseqSum1(int A[], int N) {
int ThisSum, MaxSum = 0;
int i, j, k;
for (i = 0; i < N; i++) { //i是子列左端位置。
for (j = i; j < N; j++) { //j是子列右端位置。
ThisSum = 0; //每轮都要把ThisSum归零,累加新一轮的子列和。
for (k = i; k < j; k++) //将A[i]~A[j]累加,得到子列和。
ThisSum += A[k];
if (ThisSum > MaxSum) //如果这轮的子列和比最大子列和还大,存入MaxSum.
MaxSum = ThisSum;
}
}
return MaxSum;
}
//复杂度是n的平方
int MaxSubseqSum2(int A[], int N) {
int ThisSum, MaxSum = 0;
int i, j;
for (i = 0; i < N; i++) { //i是子列左端位置。
ThisSum = 0; //A[i]~A[j]的子列和。
for (j = i; j < N; j++) { //j是子列右端位置。
ThisSum += A[j]; //对于相同的i,不同的j,只要在前面的j-1处再累加1项即可。
if (ThisSum > MaxSum) //更新MaxSum.
MaxSum = ThisSum;
}
}
return MaxSum;
}
/*返回三个整数的最大值*/
int Max3(int A, int B, int C) {
return (A > B) ? (A > C ? A : C) : (B > C ? B : C);
}
/*分治法求List[left]到List[right]的最大子列和 复杂度nlog(n)*/
int DivideAndConquer(int List[], int left, int right) {
int MaxLeftSum, MaxRightSum; //存放左右子问题的解。
int MaxLeftBorderSum, MaxRightBorderSum; //存放跨分界线的结果。
int LeftBorderSum, RightBorderSum;
int center, i;
/*递归的终止条件,子列只有1个数字*/
if (left == right) {
if (List[left] > 0) return List[left];
else return 0;
}
/* “分”的过程 */
center = (left + right) / 2; //找到中分点。
MaxLeftSum = DivideAndConquer(List, left, center); //递归求左子列和。
MaxRightSum = DivideAndConquer(List, center + 1, right); //递归求右子列和。
/*求跨分界线的最大子列和*/
MaxLeftBorderSum = 0; LeftBorderSum = 0;
for (i = center; i >= left; i--) {
LeftBorderSum += List[i];
if (LeftBorderSum > MaxLeftBorderSum)
MaxLeftBorderSum = LeftBorderSum;
}//左边扫描结束。
MaxRightBorderSum = 0; RightBorderSum = 0;
for (i = center + 1; i <= right; i++) {
RightBorderSum += List[i];
if (RightBorderSum > MaxRightBorderSum)
MaxRightBorderSum = RightBorderSum;
}//右边扫描结束。
/*返回“治”的结果*/
return Max3(MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum);
}
/*此函数用于保持接口相同*/
int MaxSubseqSum3(int List[], int N) {
return DivideAndConquer(List, 0, N - 1);
}
//在线处理——复杂度n
int MaxSubseqSum4(int A[], int N) {
int ThisSum, MaxSum, i;
ThisSum = MaxSum = 0;
for (i = 0; i < N; i++) {
ThisSum += A[i]; /* 向右累加 */
if (ThisSum > MaxSum)
MaxSum = ThisSum; /* ·发现更大和则更新当前结果 */
else if (ThisSum < 0) /* 如果当前子列和为负数 */
ThisSum = 0; /* 则不可能使后面的部分和增大,抛弃之 */
}
return MaxSum;
}
求最大子列和
于 2024-07-12 16:53:18 首次发布