1. 程式人生 > >HDU-1231 最大連續子序列

HDU-1231 最大連續子序列

ios -1 數組 結束 sample 狀態轉移方程 要求 mes 最大連續


題目

Problem Description

給定K個整數的序列{ N1, N2, ..., NK },其任意連續子序列可表示為{ Ni, Ni+1, ..., Nj },其中 1 <= i <= j <= K。最大連續子序列是所有連續子序列中元素和最大的一個,例如給定序列{ -2, 11, -4, 13, -5, -2 },其最大連續子序列為{ 11, -4, 13 },最大和為20。在今年的數據結構考卷中,要求編寫程序得到最大和,現在增加一個要求,即還需要輸出該子序列的第一個和最後一個元素。

Input

測試輸入包含若幹測試用例,每個測試用例占2行,第1行給出正整數K( < 10000 ),第2行給出K個整數,中間用空格分隔。當K為0時,輸入結束,該用例不被處理。

Output

對每個測試用例,在1行裏輸出最大和、最大連續子序列的第一個和最後一個元素,中間用空格分隔。如果最大連續子序列不唯一,則輸出序號i和j最小的那個(如輸入樣例的第2、3組)。若所有K個元素都是負數,則定義其最大和為0,輸出整個序列的首尾元素。

Sample Input

6
-2 11 -4 13 -5 -2
10
-10 1 2 3 4 -5 -23 3 7 -21
6
5 -8 3 2 5 0
1
10
3
-1 -5 -2
3
-1 0 -2
0

Sample Output

20 11 13
10 1 4
10 3 5
10 10 10
0 -1 -2
0 0 0


題解

  總體上說,本題是一道非常基本的動態規劃題。

  細節上說,數組s中的第i個儲存的是以a[i]結尾的最大連續子序列的和。狀態轉移方程非常簡單,即如果發現s[i-1]<=0,則s[i]=a[i];否則s[i]=s[i-1]+a[i]。 同時,對於全是負數的情況要特別註意。


代碼

#include <iostream>
using namespace std;
int n, smax, rmax;
int a[10005], s[10005], l[10005];
int main(){
    scanf("%d", &n);
    while(n!=0){
        for(int i=1;i<=n;i++)
            scanf(
"%d", &a[i]); smax=-1; s[0]=-1; for(int i=1;i<=n;i++){ if(s[i-1]<0){ s[i]=a[i]; l[i]=i; if(s[i]>smax){ smax=s[i]; rmax=i; } } else{ s[i]=s[i-1]+a[i]; l[i]=l[i-1]; if(s[i]>smax){ smax=s[i]; rmax=i; } } } if(smax==-1) printf("%d %d %d\n", 0, a[1], a[n]); else printf("%d %d %d\n", smax, a[l[rmax]], a[rmax]); scanf("%d", &n); } return 0; }

HDU-1231 最大連續子序列