知識點2 最大連續子串行和

2021-10-02 11:10:59 字數 2573 閱讀 4537

機試不會考裸的最大連續子串行和,而是會考一些變形,可能需要自己去轉換成最大連續子串行和,要靈活變通,不要以為背了模板就沒事了,比如這裡的題型訓練我就沒想到用最大連續子串行和?‍

今天也是為了cc,努力奮鬥的一天ヾ(≧▽≦*)o

4. **

5. 狀態的無後效性⭐⭐⭐⭐⭐

6. 題型訓練

7. 參考文件

最大連續子串行和問題如下:

給定乙個數字序列a

1a_1

a1​,a

2a_2

a2​,…,a

na_n

an​,求i,j(1≤i≤j≤n),使得a

ia_i

ai​+…+a

ja_j

aj​最大,輸出這個最大和。

下面介紹動態規劃的做法,複雜度為 o(n

)o(n)

o(n)

。令狀態dp[i]表示以a[i]作為末尾的連續序列的最大和(這裡是說a[i]必須作為連續序列的末尾)。

其實與我們的lis的dp陣列的定義很像很像,都是以xx結尾的。

以樣例為例:序列-2 11 -4 13 -5 -2,下標分別記為0,1,2,3,4,5,那麼

通過設定這麼乙個dp陣列,要求的最大和其實就是dp[0],dp[1],…,dp[n-1]中的最大值(因為到底以哪個元素結尾未知),下面想辦法求解dp陣列。

作如下考慮,因為dp[i]要求是必須以a[i]結尾的連續序列,那麼只有兩種情況:

這個最大和的連續序列只有乙個元素,即以a[i]開始,以a[i]結尾。

這個最大和的連續序列有多個元素,即從前面某處a[p]開始(p

對於情況1,最大和就是a[i]本身。

對於情況2,最大和是dp[i-1]+a[i],即a[p]+...+a[i-1]+a[i] = dp[i-1] + a[i]。由於只有這兩種情況,於是得到狀態轉移方程

dp[i]

= max

這個式子只和i和i之前的元素有關,且邊界為dp[0]=a[0],由此從小到大列舉i,即可得到整個dp陣列。接著輸出dp[0],dp[1],…,dp[n-1]中的最大值即為最大連續子串行的和。

怎麼樣,是不是很神奇?只用o(n

)o(n)

o(n)

的時間複雜度就解決了原先需要o(n

2)o(n^2)

o(n2

)複雜度問題,這就是動態規劃的魅力。

#include

#include

using

namespace std;

const

int maxn =

10010

;int a[maxn]

,dp[maxn]

;//a[i]存放以a[i]結尾的連續序列的最大和

intmain()

//邊界

dp[0]

= a[0]

;for

(int i=

1;i++i)

//dp[i]存放以a[i]結尾的連續序列的最大和,需要遍歷i得到最大的才是結果

int k=0;

for(

int i=

1;i++i)

}printf

("%d\n"

,dp[k]);

return0;

}

狀態的無後效性:例如:對動態規劃可解的問題,總會有很多涉及狀態的方式,但並不是所有狀態都具有無後效性,因此必須設計乙個擁有無後效性的狀態以及相應的狀態轉移方程,否則動態規劃就沒有辦法得到正確結果。事實上,如何設計狀態和狀態轉移方程,才是動態規劃的核心,而它們也是動態規劃最難的地方。做dp題的關鍵,就是尋找乙個好的狀態。

總結一下,動態規劃問題的時間複雜度由兩部分組成:狀態數量和狀態轉移複雜度,往往程式總的複雜度為它們的乘積。

⭐【最大連續子串行和】a - sum

演算法筆記

最大連續子串行和

最大連續子串行和問題是個很老的面試題了,最佳的解法是o n 複雜度,當然其中的一些小的地方還是有些值得注意的地方的。這裡還是總結三種常見的解法,重點關注最後一種o n 的解法即可。需要注意的是有些題目中的最大連續子串行和如果為負,則返回0 而本題目中的最大連續子串行和並不返回0,如果是全為負數,則返...

最大連續子串行和

求最大連續子串行和 分析 用乙個陣列存入輸入的數字。用乙個變數temp從0開始往後加,存放累計的和,用sum變數存放出現過的最大和。當temp遇到負數會減小,但不能初始化為0重新累計,因為後面還有可能出現正數,和會比前面sum大的情況。只有當temp遇到負數減到小於0時,temp初始化為0重新開始加...

最大連續子串行和

include include include include include include include include include include using namespace std typedef long long ll define pi 3.1415926535897932 ...