算法:Maximum Subsequence Sum

题目来源

浙大数据结构MOOC-PTA的课后题

题目内容

分析

这一题时最大子列和问题的变形,需要输出最大子列和的子列首项与末项,且在数列全为负的情况下,最大子列和为0,且需要输出首尾。而且如果出现了前后有相同都是最大子列的情况,选择前面的那一个。

我继续沿用了最大子列和问题中的在线处理算法,但是加上了对子列首尾的处理。

说实话这题有点难,我的做法也稍微有点取巧,使用专门的标志来处理非正有0的情况,不过总体来说结果是过了。

我的程序

#include <stdio.h>

int main()
{
    // 获取数据
    int size;
    scanf("%d", &size);
    int num[size];
    int max = 0, this = 0;
    // 记录首尾位置
    int start = 0, end = 0, temp = 0;
    // 记录负数和正数的个数
    int negFlag = 0;
    int posFlag = 0;
    // 在线处理,寻找最大子列和同时记录该子列和首尾位置
    for(int i = 0; i < size; i++)
    {
        scanf("%d", num + i);
        // 记录正数和负数的个数,等会有用
        if(num[i] < 0)negFlag++;
        else if(num[i] > 0)posFlag++;
        // 计算子列和
        this += num[i];
        if(this > max)
        {
            max = this;
            // 当最大子列和发生了变化,记录其末尾,并将之前缓存的首部放入start
            end = i;
            start = temp;
        }
        else if(this < 0)
        {
            this = 0;
            // 当在线处理发现了子列和为负数的情况,需要丢弃前面的子列和,此时使用temp记录此次更新,因为它可能成为最大子列和的首项
            temp = i + 1;
        }
    }
    if(negFlag == size)printf("%d %d %d", 0, num[0], num[size - 1]);	// 全是负数,输出最大值0和首尾项
    else if(posFlag > 0)printf("%d %d %d", max, num[start], num[end]);	// 如果有正数,则必然存在非零最大子列
    else if(posFlag == 0)printf("0 0 0");	// 如果没有正数,又不全是负数,则最大子列和是0,且子列内容也全是0,直接输出0
    return 0;
}

运行结果

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值