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;
}
相關文章
相關標籤/搜索