最大子列和问题2020.09.13

#include <stdio.h>
#define MaxSize 100000
// 穷举法
int MaxSubseqSum1(int List[], int N)
{
    int i, j, k;
    int ThisSum, Maxsum = 0;
    for(i = 0; i < N; i++)
    {
        for(j = i; j < N; j++) //the right limitation
        {
            ThisSum = 0;
            for(k = i; k < j; k++)
                ThisSum += List[k];
            if(ThisSum > Maxsum)
                Maxsum = ThisSum;
        }
    }
    return Maxsum;
}

//部分穷举法
int MaxSubseqSum2(int List[], int N)
{
    int i, j, k;
    int ThisSum, Maxsum = 0;
    for(i = 0; i < N; i++) // the left limitation
    {
        ThisSum = 0;
        for(j = i; j < N; j++) // the right limitation
        {
            ThisSum += List[j]; // we don't need to add the List[x] twice
            if(ThisSum > Maxsum)
                Maxsum = ThisSum;
        }
    }
    return Maxsum;
}

//分而治之法

int Max3(int A, int B, int C)
{
    return A > C ? A > B ? A : B : B > C ? B : C;
}

int DivideAndConquer(int List[], int left, int right)
{
    int MaxLeftSum, MaxRightSum; // 存放左右子问题结果
    int MaxLeftBorderSum, MaxRightBorderSum; // 存放跨边界结果

    int LeftBorderSum, RightBorderSum;
    int center, i;

    if(left == right) // 递归终止,仅有一个数字
    {
        if(List[left] > 0) return List[left];
        else return 0;
    }

    // division
    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, MaxRightBorderSum + MaxLeftBorderSum);
}

// 保持接口一致
int MaxSubseqSum3(int List[], int N)
{
    return DivideAndConquer(List, 0, N - 1);
}


//在线处理

int MaxSubseqSum4(int List[], int N)
{
    int i;
    int ThisSum, MaxSum;

    ThisSum = MaxSum = 0;
    for(i = 0; i < N; i++)
    {
        ThisSum += List[i];
        if(ThisSum > MaxSum)
            MaxSum = ThisSum;
        else if (ThisSum < 0)
            ThisSum = 0;
    }
    return MaxSum; 
}


//主程序接口

int main()
{
    int List[MaxSize + 1];
    int N;
    scanf("%d", &N);
    for(int i = 0; i < N; i++)
        scanf("%d", &List[i]);
    printf("%d", MaxSubseqSum4(List, N));
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值