在线处理 O(N)
#define k 10000
int MaxSubseqeSum(int a[],int n);
int main()
{
int n;
cin >> n;
int a[k] = { 0 };
for (int i = 0; i < n; i++)
cin >> a[i];
cout<< MaxSubseqeSum(a, n);
return 0;
}
int MaxSubseqeSum(int a[], int n)
{
int maxsum = 0, nowsum = 0;
for (int i = 0; i < n; i++)
{
nowsum += a[i];
if (nowsum > maxsum)
maxsum = nowsum;
if (nowsum < 0)
nowsum = 0;
}
return maxsum;
}
分而治之 O(NlogN)
- 将数列一分为二为左右两个子序列,分别求解左侧、右侧、跨中心分界线的最大子列和,整个数列的最大子列和一定在这三者中;
- 对左、右半侧的子列继续一分为二重复上述操作,直到一分为二到子列只有一个元素;
- 从中间分解线向左右两边扫描,找出跨界最大子列和
- 以上操作均由递归完成
#define k 10000
int DAC(int a[], int Left, int Right);//DAC-Divide And Conquer
int Max_3(int a, int b, int c);
int DAC(int a[], int Left, int Right)
{
int center;
/*只有一个元素*/
if (Left == Right)
if (a[Left] > 0)
return a[Left];
else
return 0;
/*分*/
center = (Left + Right) / 2;//找中心元素
int LSumMax, RSumMax; //存放左右子问题的解
LSumMax=DAC(a, Left, center);//递归求左半边
RSumMax=DAC(a, center + 1, Right);//递归求右半边
/*求解跨分解线子列*/
int LSideSumMax = 0, RSideSumMax = 0; //左(右)侧最大子列和
int LSideSum=0, RSideSum=0;
//扫描左边
for (int i = center; i >= Left; i--)
{
LSideSum += a[i];
DAC(a, Left, center);
if (LSideSum > LSideSumMax)
LSideSumMax = LSideSum;
}
//扫描右边
for (int i = center + 1; i < Right; i++)
{
RSideSum += a[i];
DAC(a, center + 1, Right);
if (RSideSum > RSideSumMax)
RSideSumMax = RSideSum;
}
/*返回治的结果*/
return Max_3(LSumMax, RSumMax, RSideSumMax + LSideSumMax);
}
int main()
{
int n;
cin >> n;
int list[k] = { 0 };
for (int i = 0; i < n; i++)
cin >> list[i];
int R = n - 1;//数组最后元素下标
cout << MaxSubsequeSum(list, R);
return 0;
}
int Max_3(int a, int b, int c)
{
if (a < b) a = b;
if (a < c) a = c;
return a;
}
int MaxSubsequeSum(int a[], int n)//用于保证接口相同
{
return DAC(a, 0, n - 1);
}
三重循环O(N³)
#include "head.h"
#define MAX 10000
int SubseqeMax(int a[], int n);
int SubseqeMax(int a[], int n)
{
int summax = 0;
int sum = 0;
for (int i = 0; i < n; i++) //标记子列左端
{
for (int j = i; j < n; j++) //标记子列右端
{
sum = 0;//每次求和前清除
for (int k = i; k < j; k++)//求和
{
sum += a[k];
if (sum > summax)
summax = sum;
}
}
}
return summax;
}
int main()
{
int n;
cin >> n;
int a[MAX] = { 0 };
for (int i = 0; i < n; i++)
cin >> a[i];
cout << SubseqeMax(a, n);
return 0;
}
二重循环 T(O)=(N²)
#define MAX 10000
int SubseqeMax(int a[], int n);
int SubseqeMax(int a[], int n)
{
int summax = 0;
int sum = 0;
for (int i = 0; i < n; i++) //i是子列左端位置
{
sum = 0; //A[i]~A[j]的子列和
for (int j = i; j < n; j++) //j是子列右端位置
{
sum += a[j]; //对于相同的i,不同的j,只要在j-1处再累加1项即可
if (sum > summax)
summax = sum;
}
}
return summax;
}
int main()
{
int n;
cin >> n;
int a[MAX] = { 0 };
for (int i = 0; i < n; i++)
cin >> a[i];
cout << SubseqeMax(a, n);
return 0;
}