問題描述:給定一個序列a[1],a[2]...a[n],求解其連續子序列中元素和的最大值
例如: 6 -1 5 4 -7 這個序列最大連續子序列和為14
具體問題見: HDOJ 1003 TZU 1202
這個問題在《資料結構與演算法分析--c語言描述》(weiss著)中文版第13頁(英文版第18頁)中也有描述。在第21頁給出了一個演算法程式:
int MaxSubsequenceSum(const int A[], int N) { int ThisSum,MaxSum,j; ThisSum = MaxSum = 0; for(j = 0; j < N; j++) { ThisSum += A[j]; if(ThisSum > MaxSum) MaxSum = ThisSum; else if(ThisSum < 0) ThisSum = 0; } return MaxSum; }
我將演算法寫成了下面的樣子:
int MaxSubsequenceSum(const int A[], int N) { int ThisSum,MaxSum,j; ThisSum =0, MaxSum =INT_MIN; for(j = 0; j < N; j++) { ThisSum += A[j]; if(ThisSum > MaxSum) MaxSum = ThisSum; if(ThisSum < 0) ThisSum = 0; } return MaxSum; }
此時必須將else這個關鍵字刪除,這是因為使用了不同的值來初始設定變數引起的。書本中的例子能夠始終保證MaxSum為非負值。而我改寫後的演算法在很多情況下MaxSum都會是負數
我的acm程式如下(在上面兩個網站都是ac):
#include <stdio.h> #include <limits.h> #define MAX 100000+100 int main(void) { int n; int m; int a[MAX]; int i,j; int thisSum,maxSum; int maxStart,maxEnd,thisStart; scanf("%d",&n); for(i = 1; i <= n; i++) { scanf("%d",&m); for(maxStart=maxEnd=thisStart=thisSum=0,maxSum=INT_MIN,j = 0; j < m; j++) { scanf("%d",&a[j]); thisSum += a[j]; if(thisSum > maxSum) { maxSum = thisSum; maxStart = thisStart; maxEnd = j; } if(thisSum < 0) { thisSum = 0; thisStart = j+1; } } if(i > 1) printf("\n"); printf("Case %d:\n",i); printf("%d %d %d\n",maxSum,maxStart+1,maxEnd+1); } return 0; }
程式主要部分還是上面的演算法,只是加上了對子序列首尾索引號的處理。