//手撕最大子序列和问题
#include <iostream>
#include <algorithm>
using namespace std;
int MaxSubsequenceSum_A(int A[], int N);
int MaxSubsequenceSum_B(int A[], int N);
int MaxSubsequenceSum_C(int A[], int N);
int MaxSubsequenceSum_D(int A[], int N);
int MaxSubSum(int A[], int Left, int Right);
int main(){
int a[100];
int N;
cin >> N;
for(int i=0; i<N; i++)
{
cin >> a[i];
}
int res = MaxSubsequenceSum_D (a,N);
cout << res;
return 0;
}
int MaxSubsequenceSum_A(int A[], int N)
{
int ThisSum, MaxSum, i, j, k;
MaxSum = 0;
for(i=0; i<N; i++)
{
for (j=i; j<N; j++)
{
ThisSum = 0;
for(k=i; k<=j; k++)
{
ThisSum += A[k];
}
if( ThisSum > MaxSum )
{
MaxSum = ThisSum;
}
}
}
return MaxSum;
//最简单的暴力穷举,找到最大的,代码没有经过任何优化三层嵌套循环O(N^3);
}
int MaxSubsequenceSum_B(int A[], int N)
{
int ThisSum, MaxSum , i, j;
for(i=0; i<N; i++)
{
ThisSum = 0;
for(j=i; j<N; j++)
{
ThisSum += A[j];
if( ThisSum > MaxSum ){
MaxSum = ThisSum;
}
}
}
return MaxSum;
//对穷举法进行了有限的优化,减免了一层循环。
//按照教材所说,并不是所有的三层循环都可以做这种优化(而且效果实在有限)
}
int MaxSubSum(int A[], int Left, int Right)//错点1.递归求解要有基准情况
{
int Center, Res;
int MaxRightSum, MaxLeftSum;
int MaxRightBorderSum, MaxLeftBorderSum;
int LeftBorderSum=0, RightBorderSum=0;
if(Left==Right){
if(A[Left]>0)
return A[Left];
else
return 0;
} //递归的基准情形
Center = (Left+Right)/2;
MaxRightSum = MaxSubSum(A, Center+1, Right);
MaxRightSum = MaxSubSum(A, Left, Center);//递归求解左右区域的最大子序列和
MaxRightBorderSum = 0;
MaxLeftBorderSum = 0;
for(int i=Center; i>=Left; i--)
{
LeftBorderSum += A[i];
if(LeftBorderSum > MaxLeftBorderSum)
{
MaxLeftBorderSum = LeftBorderSum;
}
}
for(int i=Center+1; i<=Right; i++)
{
RightBorderSum += A[i];
if(RightBorderSum > MaxRightBorderSum)
{
MaxRightBorderSum = RightBorderSum;
}
}
Res = max(MaxRightSum,MaxRightSum);
Res = max(Res, MaxRightBorderSum+MaxLeftBorderSum);
return Res;
}
int MaxSubsequenceSum_C(int A[], int N)
{
return MaxSubSum(A, 0, N-1);
}
int MaxSubsequenceSum_D(int A[], int N)
{
int ThisSum =0;
int MaxSum =0;
for(int i=0; i<N; i++){
ThisSum += A[i];
if(ThisSum > MaxSum){
MaxSum = ThisSum;
}
if(ThisSum<0){
ThisSum =0;
}
}
return MaxSum;
//联机算法,看懂这个算法并不难,但是难在理解和自己编写。
//梳理一下算法思路,试图去理解
//当ThisSum>0时,他就有成为最大和的潜力,但是TS是负数的话就完全没有这种可能,前面的数字就可以舍弃
//说个具体的例子:-1 1 2 3 -4 5
//我们遇到的第一个数字是-1,TS=-1,这时不论下一个数字是什么,TS都会导致新的TS'减小,所以我们直接归零
//事实上就是舍弃了第一个数(-1)
}
回顾最大子序列和问题
最新推荐文章于 2024-10-31 19:10:01 发布