HDU-1231 最大連續子序列
阿新 • • 發佈:2017-10-07
ios -1 數組 結束 sample 狀態轉移方程 要求 mes 最大連續
對每個測試用例,在1行裏輸出最大和、最大連續子序列的第一個和最後一個元素,中間用空格分隔。如果最大連續子序列不唯一,則輸出序號i和j最小的那個(如輸入樣例的第2、3組)。若所有K個元素都是負數,則定義其最大和為0,輸出整個序列的首尾元素。
題目
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
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 最大連續子序列