機試不會考裸的最大連續子串行和,而是會考一些變形,可能需要自己去轉換成最大連續子串行和,要靈活變通,不要以為背了模板就沒事了,比如這裡的題型訓練我就沒想到用最大連續子串行和?
今天也是為了cc,努力奮鬥的一天ヾ(≧▽≦*)o最大連續子串行和問題如下:4. **
5. 狀態的無後效性⭐⭐⭐⭐⭐
6. 題型訓練
7. 參考文件
給定乙個數字序列a1a_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]
。由於只有這兩種情況,於是得到狀態轉移方程:這個式子只和i和i之前的元素有關,且邊界為dp[0]=a[0],由此從小到大列舉i,即可得到整個dp陣列。接著輸出dp[0],dp[1],…,dp[n-1]中的最大值即為最大連續子串行的和。dp[i]
= max
怎麼樣,是不是很神奇?只用o(n
)o(n)
o(n)
的時間複雜度就解決了原先需要o(n
2)o(n^2)
o(n2
)複雜度問題,這就是動態規劃的魅力。
狀態的無後效性:例如:對動態規劃可解的問題,總會有很多涉及狀態的方式,但並不是所有狀態都具有無後效性,因此必須設計乙個擁有無後效性的狀態以及相應的狀態轉移方程,否則動態規劃就沒有辦法得到正確結果。事實上,如何設計狀態和狀態轉移方程,才是動態規劃的核心,而它們也是動態規劃最難的地方。做dp題的關鍵,就是尋找乙個好的狀態。#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;
}
總結一下,動態規劃問題的時間複雜度由兩部分組成:狀態數量和狀態轉移複雜度,往往程式總的複雜度為它們的乘積。
⭐【最大連續子串行和】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 ...