演算法總結 DP 求子陣列的最大和

2021-07-04 12:10:46 字數 2441 閱讀 7825

快要畢業了,逐步把之前做過的一些演算法和資料結構,專案相關資料總結整理一下,一來溫習一下之前的知識,二來記錄下學習點滴,方便之後的學習。

[plain]view plain

copy

print?

題目描述:給定乙個整數陣列,陣列中有正數也有負數,陣列中連續的乙個或者多個整數組成乙個子陣列,每個子陣列都有乙個和,求給定陣列的最大子陣列和。也成為「最大子段和」問題。要求時間複雜度為o(n).  

該題目是乙個簡單的dp問題。演算法的思路很多,但是如果要滿足時間複雜度為o(n)。一般的演算法是達不到的。

dp解決該問題的思路是:掃瞄陣列,記錄當前陣列的和 與 已經記錄的最大的子陣列的和。如果當前記錄的和已經是負數,那麼捨棄它,並重新設定當前陣列和為當前元素的值。否則,比較當前陣列的和與已經記錄的最大的子陣列的和大小,如果比最大的和大,就更新最大和。掃瞄一遍完成統計,滿足題目的要求。

演算法實現如下:

[cpp]view plain

copy

print?

#include 

#include 

#include 

intmaxsubsum(

int*a,

intn)  

else

if(cursum > max)  

}  return

max;  

}  int

main();  

printf("%d \n"

,maxsubsum(a,8));  

system("pause"

);  

return

0;  

}  

進一步考慮,如果不僅僅是求最大和,而且要求最大欄位的開始和結束索引。那麼應該怎麼做呢。

演算法的思路還是一樣的,唯一不同的是,我們需要增加兩個變數start和end用來記錄開始和結束的索引。並且在發生變化的時候更新相應的值,那麼掃瞄一遍一樣可以求出最大子段的開始結束索引。

演算法如下

[cpp]view plain

copy

print?

#include 

#include 

#include 

intmaxsubwithindex(

int*a,

intn,

int&start,

int&end)  

else

if(cursum > max)  

}  return

max;  

}  int

main();  

intstart = 0,end = 0;  

printf("ok:%d \n"

,maxsubwithindex(a,8,start,end));  

printf("starts:%d ends:%d \n"

,start,end);  

system("pause"

);  

return

0;  

}  

進一步拓展,對於乙個二維矩陣,一樣存在乙個最大的子矩陣,使得該子矩陣的和為最大。思考一下:這個問題跟之前的最大欄位和的問題有什麼相似之處嗎?

編碼之前,我們不妨先畫個圖:

如果把每一列的和都當做乙個元素的話,那麼問題是不是跟一維的求最大欄位和的問題類似呢?我們只需要順序掃瞄一次矩陣,並求出每個子矩陣的和,然後與最大的和比較,最後可以求出最大子矩陣的和。

演算法對應的**如下:

[cpp]view plain

copy

print?

#include 

#include 

#define n 3

intmaxsum(

int*a,

intn)  

else

if(sum >max)  

}  return

max;  

}  int

maxsubmatrix(

int** a,

intm,

intn)  

for(j = i;j 

sum = maxsum(b,n);  

if(sum > max)  

}  }  

return

max;  

}  main()  

}  printf("%d\n"

,maxsubmatrix(a,m,n));  

for(

inti = 0;idelete

a[i];  

delete

a;  

}  }  

求子陣列的最大和 DP

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

求子陣列最大和

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

求子陣列的最大和

題目 輸入乙個整形陣列,陣列裡有正數也有負數。陣列中連續的乙個或多個整數組成乙個子陣列,每個子陣列都有乙個和。求所有子陣列的和的最大值。要求時間複雜度為o n 本題最初為2005年浙江大學計算機系的考研題的最後一道程式設計題,在2006年裡包括google在內的很多知名公司都把本題當作面試題。由於本...