1003 最大連續子串和

2021-06-21 06:41:12 字數 2205 閱讀 2783

乙個經典問題,對於乙個包含負值的數字串array[1...n],要找到他的乙個子串array[i...j](0<=i<=j<=n),使得在array的所有子串中,array[i...j]的和最大。

這裡我們需要注意子串和子串行之間的區別。子串是指數組中連續的若干個元素,而子串行只要求各元素的順序與其在陣列中一致,而沒有連續的要求。對於乙個元素數為n的陣列,其含有2^n個子序列和n(n+1)/2個子串。如果使用窮舉法,則至少需要o(n^2)的時間才能得到答案。卡耐基梅隆大學的jay kadane

要說明kadane演算法的正確性,需要兩個結論。首先,對於array[1...n],如果array[i...j]就是滿足和最大的子串,那麼對於任何k(i<=k<=j),我們有array[i...k]的和大於0。因為如果存在k使得array[i...k]的和小於0,那麼我們就有array[k+1...j]的和大於array[i...j],這與我們假設的array[i...j]就是array中和最大子串矛盾。

其次,我們可以將陣列從左到右分割為若干子串,使得除了最後乙個子串之外,其餘子串的各元素之和小於0,且對於所有子串array[i...j]和任意k(i<=k我們假設array[p...q],是array的和最大子串,且array[p...q],跨越了array[i...j],array[j+1...k]。根據我們的分組方式,存在i<=marray[p...q],否array[j+1...n]>array[p...q],無論誰大,我們都可以找到比array[p...q]和更大的子串,這與我們的假設矛盾,所以滿足條件的array[p...q]不可能跨越兩個子串。對於跨越更多子串的情況,由於各子串的和均為負值,所以同樣可以證明存在和更大的非跨越子串的存在。對於單元素和最大的特例,該結論也適用。

根據上述結論,我們就得到了kadane演算法的執行流程,從頭到尾遍歷目標陣列,將陣列分割為滿足上述條件的子串,同時得到各子串的最大字首和,然後比較各子串的最大字首和,得到最終答案。我們以array=為例,來簡單說明一下演算法步驟。通過遍歷,可以將陣列分割為如下3個子串(-2),(1,-3),(4,-1,2,1,-5,4),這裡對於(-2)這樣的情況,單獨分為一組。各子串的最大字首和為-2,1,6,所以目標串的最大子串和為6。

下面是實現**:

int kadane(const int array, size_t length, unsigned int& left, unsigned int& right)  

} else

} return max;

}

這裡我們需要注意,對於陣列元素全為負的情況,由於不滿足上述的兩條結論,所以kadane演算法無法給出正確答案。

該問題是2023年ulf grenander提出的乙個數字影象方面的問題,2023年jay kadane才給出了這個優美的解決方案。有些問題,看似解法簡單,但是實際上其原理,要比**複雜得多。

下面是我寫的1003號題目**,實現演算法與上面大致一樣,但是**寫的有點亂,不夠簡潔,精煉

# include # include # define cases_max 20

using namespace std;

void findmaxsum(int case_num,int nums_len,int * nums)

else if(first_flag==0) //第乙個非負數以後數字處理判斷

if(t_sum > max_sum) //臨時連續子串和比已經儲存的最大連續子串和大處理,賦值給最大連續字串和

else if(t_sum < 0 && t_right+1=0) //臨時字串和小於0,臨時連續字串斷開,從下一位非負數開始

} } if(first_flag == 1) //沒有找到非負數,也就是陣列全部負數處理 }

if(case_num != 0)

cout<>num_case;

int * case_lens = (int *)malloc(sizeof(int) * num_case);//int型陣列case_lens儲存每組資料的長度

for( i = 0;i < num_case; ++i)

for(i = 0;i < num_case;++i)

findmaxsum(i,(*(case_lens + i)), nums_address[i]);

return 0;

}

HDU dp練習 1003 最大連續子串行

題目 problem description 給定k個整數的序列,其任意連續子串行可表示為,其中 1 i j k。最大連續子串行是所有連續子串行中元素和最大的乙個,例如給定序列,其最大連續子串行為,最大和 為20。在今年的資料結構考卷中,要求編寫程式得到最大和,現在增加乙個要求,即還需要輸出該 子串...

最大連續子串行和

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

最大連續子陣列和

題目描述 輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值,要求時間複雜度為o n 例如輸入的陣列為 1,2,3,10,4,7,2,5 和最大的子陣列為 3,10,4,7,2 因此輸出為該子陣列的和18。思路 採用貪婪法...