題目描述:
最大子段和:給定乙個長度為n的一維陣列a,請找出此陣列的乙個子陣列,使得此子陣列的和sum=a[i]+a[i+1]+……+a[j]最大,其中i>=0,i=i,j
例如:31 -41 59 26 -53 58 97 -93 -23 84
子矩陣59+26-53+58+97=187為所求的最大子陣列。
第一種:直接窮舉法:
1 #include 2時間複雜度為o(n*n*n)using
namespace
std; 34
intmain()
5;
7int
sum;
8int maxsofar=0
; 9
for(int i = 0 ;i< 10;++i)//
控制子陣列開始位置
10
20}
2122 cout<
maxsofar:
"2324
return
0;
25 }
第二種:帶記憶的遞推法:
1 #include 2顯然第二種方法比第一種方法有所改進,時間複雜度為o(n*n)。using
namespace
std; 34
intmain()
5;
7int
sum;
8int maxsofar=0
; 9
int current[10
];
10 current[0]=a[0
];
11for(int i=1 ;i< 10;++i) //
首先生成個數為1,2,3……10個的陣列和
12
1516
for(int i=0;i< 10;++i)
17
25}
2627 cout<
maxsofar:
"2829
return
0;
30 }
第三種:動態規劃
下面我們來分析一下最大子段和的子結構,令b[j]表示從a[0]~a[j]的最大子段和。
b[j]的當前值只有兩種情況:
(1) 最大子段一直連續到a[j]
(2) 以a[j]為起點的子段 //如果不是第(1)種,則(1)肯定為負,捨去
還有一種情況,那就是最大子段沒有包含a[j],如果沒有包含a[j]的話,那麼在算b[j]之前的時候我們已經算出來了,注意我們只是算到位置為j的地方,所以最大子段在a[j]後面的情況我們可以暫時不考慮。
由此我們得出b[j]的狀態轉移方程為:b[j]=max,
所求的最大子段和為max; 78
int b=0,sum=a[0
]; 910
for(int i=0;i<10;i++)
11
1920
21 cout<
maxsum:
"2223
return
0;
24 }
演算法複雜度:o(n)
這個演算法只能夠求得最大子段和,不能夠明確得出最大子段的位置。
1
public
int maxsubsequence(int
array)
5int max =integer.min_value;
6int maxsub = new
int[array.length];
7 maxsub[0] = array[0];
8 max=maxsub[0];910
for (int i = 1; i < array.length; i++)
15}
16return
max;
17 }
view code
最大子段和問題
給定n個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如a i a i 1 a j 的子段和的最大值。當所給的整均為負數時定義子段和為0 分治法 分析 首先將陣列分為兩部分,最大子段和 可以在陣列的左半部分也可以在右半部分,也可以橫跨分割點,因此我們只需要用分治思想求出左邊最大...
最大子段和問題
給定n 個整數 有可能是負數 組成的序列,要求分別用蠻力法,減治法和動態規劃法,求最該序列的最大子段和,並對它們的效率進行比較分析。也稱窮舉法或列舉法,是一種簡單直接地解決問題的方法,常常基於問題的描述,所以,蠻力法也是最容易應用的方法。它依賴的基本技術是遍歷,採用一定的策略依次處理待求解問題的所有...
最大子段和問題
問題描述 給定n個整數 可能為負數 組成的序列a 1 a 2 a 3 a n 求該序列如 a i a i 1 a j 當所給的整數均為負數時定義子段和為0.如果序列中全部是負數則 最大子段和為0,依次所定義 所求的最優值max,1 i問題解析 動態規劃演算法 dp i 包含元素i的子段和 dp 0 ...