PTA 1007 Maximum Subsequence Sum

题目是浙大版数据结构视频里的原题,大意是说给出一个整数序列,让你求出和最大的连续子序列。最后输出子序列的和以及子序列的第一个数最后一个数。若是给出的序列全是负数的话,就输出0以及整个序列的第一个数和最后一个数。ios


这道题大体有两种作法,一种是暴力枚举每个子序列,固然毫无疑问会超时,还有一种是在线处理。个人在线处理作法是:c++

  • 先定义一个last表示最大子序列的最后一个数,定义一个maxSum表示目前为止最大的子序列的和。定义一个sum用于表示当前子序列的和。数据结构

  • 从第一个数开始处理。spa

    • 把当前的数加到sum上,若是加上以后sum小于0,说明不管以后的数是什么,加上当前这个序列以后都会比原来的小,那么咱们果断把sum清零,从新开始累计。
    • 以后判断sum是否比maxSum大,若是大的话,咱们更新last和maxSum。令last等于当前数的下标,maxSum等于sum。
  • 继续日后处理,直到序列结束。code

在上边那样处理完后,咱们找出最大子序列和的问题是解决了。但还有一个问题,若是序列全是负数的话,sum会是0,last最后也会是0。若是序列中只有负数和0的话,最后的结果也会是sum和last都是0。这样就会致使两种状况没法区分。个人解决方法是最后从第1个数开始再找一遍,一旦找到0就能够断定是第二种状况,而后输出0 0 0,若是没有找到0,那就按第一种状况输出。视频

AC代码以下blog

#include <iostream>
#include <algorithm>
#include <stdio.h>
using namespace std;

int arr[10001];

int main()
{
    int k;
    cin >> k;

    for (int i = 0; i < k; i++)
        scanf("%d", arr + i);

    int sum = 0, maxSum = 0, last = 0, start = 0;

    for (int i = 0; i < k; i++)
    {
        sum += arr[i];
        if (sum < 0)
            sum = 0;
        else if (sum > maxSum)
        {
            maxSum = sum;
            last = i;
        }
    }
    int t = 0;
    start = last;
    while (start >= 0)
    {
        t += arr[start];
        if (t == maxSum)
            break;
        start--;
    }

    if (maxSum == 0)
    {
        bool flag = false;
        for (int i = 0; i < k; i++)
            if (arr[i] == 0)
            {
                printf("0 %d %d", arr[i], arr[i]);
                flag = true;
                break;
            }
        if (flag == false)
            printf("0 %d %d", arr[0], arr[k - 1]);
    }
    else
    {
        printf("%d %d %d", maxSum, arr[start], arr[last]);
    }

    return 0;
}
相关文章
相关标签/搜索