PAT(甲) 1007. Maximum Subsequence Sum (25)

1007. Maximum Subsequence Sum (25)

题目地址:1007. Maximum Subsequence Sum (25)
题目描述:

Given a sequence of K integers { N1, N2, …, NK }. A continuous subsequence is defined to be { Ni, Ni+1, …, Nj } where 1 <= i <= j <= K. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.
Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.


  • 输入格式
    Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K (<= 10000). The second line contains K numbers, separated by a space.

  • 输出格式
    For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j (as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.


解题方法:
本题可以用在线处理的方法进行最大子列和的求解,具体方式是设置一个临时变量TempSubSum和最大子列和MaxSubSum。每输入一次就加给TempSubSum,然后根据TempSubSum与MaxSubSum的比较来确定是否更新MaxSubSum,如果TempSubSum小于0,就抛弃当前的子列,TempSubSum重新赋值为0。


易错点:
这道题的易错点有很多,虽然有些易错点并没有在测试样例体现,主要如下:
1. 必须初始化i,j的下标为0(我这里变量名叫TempStart,TempEnd)
2. 要对输入的有一个是否出现非负数的判断,防止0 -1 -1这样的序列归为全为负数的情况
3. MaxSubSum的要设为接近0的浮点型负数,也是对像-1 -1 0这样的序列进行处理,如果MaxSubSum设为0,那么将无法更新j(TempEnd),导致输出错误。此外,在最后还需要对MaxSubSum进行强制类型转换,转为int型,防止出现输入全负,无法更新MaxSubSum的结果,同时也方便最后输出。
4. 要对子列长度为1的情况进行处理




程序:

#include <stdio.h>

int main(int argc, char const *argv[])
{
    int N, TempSubSum = 0;
    int TempStart = 0, TempEnd = 0,Temp, flag = 1, flagNeg = 1; /* 必须初始化为0 */
    double MaxSubSum = -0.999;  /* 这样写的目的是出现子列中最大数为0的情况的处理 */
    scanf("%d", &N);
    int Arr[N];
    for (int i = 0; i < N; i++)
    {
        scanf("%d", &Arr[i]);
        if (N == 1)
        {   /* 针对特殊情况该序列只有一个元素 */
            if (Arr[i] > 0)
                printf("%d %d %d\n", Arr[i], Arr[i], Arr[i]);
            else
                printf("%d %d %d\n", 0, Arr[i], Arr[i]);
            return 0;
        }
        TempSubSum += Arr[i];
        if (TempSubSum > MaxSubSum)
        {   /* 如果当前的子列和大于最大子列和 */
            MaxSubSum = TempSubSum;
            TempEnd = i;    /* 保存最大子列和的尾元素下标 */

            if (flag == 0)
            {   /* 这个条件用于判定是否最大子列和的起始下标改变 */
                TempStart = Temp;
                flag = 1;
            }
        }
        if (TempSubSum < 0)
        {   /* 如果当前子列和小于0 抛弃 */
            Temp = i+1;
            TempSubSum = 0;
            flag = 0;
        }
        else
            flagNeg = 0;
    }
    int Max = MaxSubSum;        /* 这一步转换是把MaxSubSum转为整形,即使MaxSubSum是-0.999,也会变成1 */ 
    if (Max == 0 && flagNeg)    /* 这里是考虑到序列有0和负数组成,才需要flagNeg判断 */
        printf("0 %d %d\n", Arr[0], Arr[N-1]);
    else
        printf("%d %d %d\n", Max, Arr[TempStart], Arr[TempEnd]);
    return 0;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值