最大連續和

2021-07-10 22:48:23 字數 1890 閱讀 3652

這個問題對我來說還挺難的,當初做dp時水過去了,但沒徹底理解,這次打算好好分析一下,爭取徹底搞懂。

首先,像:1 -1 2 2 3 -3 4 -4 5 -5這樣的數列,想要找連續最大和,可以有很多種方法,從最慢的列舉o(n^3)到最快的動態規劃o(n),毫無疑問,我們要選擇複雜度低的演算法。所以我這裡就只分析兩種:分治法o(nlogn)和動態規劃o(n)。

分治法一般分為如下三個步驟:

劃分問題:把問題的例項劃分成子問題。

遞迴求解:遞迴解決子問題。

合併問題:合併子問題的解得到原問題的解

要求連續最大和,最大的難點在於怎麼處理負數,我們將數列拆分成兩段後,遞迴得到兩段中對應的最大值,那麼區間中對應的單獨的最大和已經求出來了,接下來要找分界點在區間中間的最大和,那麼就分別從分界點從左和右找最大和,加起來與單獨的最大和比較,這樣就可以求出總的最大和。

int maxsum(int x, int y)			//區間在[x,y)

v = 0; right = a[m];

for (int i = m; i < y; i++) //從分界點右邊找連續的最大和

return max(maxs, left + right); //兩邊單獨的最大值與分界點兩邊合併後最大值比較,主要考慮負數影響

}

動態規劃的要點是用乙個陣列儲存過程中的狀態,有三種方法:

第一種比較簡單,只要簡單的按照正負思考即可,但是最後需要遍歷一遍。用乙個b[n]陣列儲存狀態,如果b[k-1]<0,那麼加乙個負數肯定會減少,所以直接從a[k]開始,b[k]=a[k];如果b[k-1]>0,那麼加乙個正數肯定變大,所以b[k]=b[k-1]+a[k]。

狀態轉移方程為b[k]=max(b[k-1]+a[k],a[k])

void dp()

printf("%d\n", max);

}

第二種方法就比較難想到了,但好處是最後不用遍歷一遍,可以考慮陣列的第乙個元素,以及最大的一段陣列(a[i], ..., a[j]),和a[0]的關係,有以下三種情況:

1. 當0 = i = j 時,元素a[0]本身構成和最大的一段,all[0]=a[0]

2. 當0 = i < j 時,和最大的一段以a[0]開始,all[0]+start[1]

3. 當0 < i 時, 元素a[0]和最大的一段沒有關係,all[0]=all[1]

從上面3中情況可以看出。可以將乙個大問題(n個元素陣列)轉化為乙個較小的問題(n-1個元素的陣列)。

假設已經知道(a[1], ...,a[n-1])中和最大的一段陣列之和為all[1],並且已經知道(a[1],...,a[n-1])中包含a[1]的和最大的一段陣列為start[1]。那麼不難看出 (a[0], ..., a[n])中問題的解all[0] = max。這樣all[0]表示的就是總的0~n的最大和。倒序dp即可。

start陣列記錄的就是包括當前值的連續最大和,比如1,-2,3,-2,start[3]就截斷從3開始。而all陣列則考慮要不要加a[k],說白了,就是三種情況:當前值不加,只有乙個當前值,當前值加上前面的包含前乙個值的最大和(要連續)。

狀態轉移方程為:all[k]=max(all[k+1],a[k],a[k]+start[k+1])

void dp()

printf("%d\n", all[0]);

}

第三種結合了前兩種的優點,不用遍歷而且便於理解:

首先需要乙個dp[k]儲存第k個數之前的最大連續和,然後還要乙個sum和temp,sum用來不斷累加a[k],如果sum>temp,就把temp更新為sum,並且如果sum<0,將sum重新賦值為0。

void dp()

}

最大連續和

求陣列中數的最大連續和,如 1,1,1,1,1 最大連續和為3 一 動態規劃 當我們從頭到尾遍歷這個陣列的時候,對於陣列裡的乙個整數,它有幾種選擇呢?它只有兩種選擇 1 加入之前的subarray 2.自己另起乙個subarray。那什麼時候會出現這兩種情況呢?設狀態為f j 表示以s j 結尾的最...

最大連續和

給出乙個長度為n的序列a1,a2,an,求最大連續和 使用列舉 時間複雜度o n 3 best a 1 初始最大值 for int i 1 i n i 設si a1 a2 ai,則ai ai 1 aj sj si 1 連續子串行的和等於兩個字首之差 時間複雜度o n 2 s 0 0 for int ...

最大連續和

思路 設sum i 為前i個元素中,包含第i個元素且和最大的連續子陣列,result 為已找到的子陣列中和最大的。對第i 1個元素有兩種選擇 做為新子陣列的第乙個元素 放入前面找到的子陣列。sum i 1 max a i 1 sum i a i 1 result max result,sum i 方...