演算法導論筆記 04最大子陣列矩陣乘法以及遞迴式求解

2021-07-01 22:08:01 字數 3037 閱讀 3043

最大子陣列,給定陣列,在這個陣列中找到這樣的子陣列:子陣列的和是所有子陣列中最大的(子陣列必須是連續的)。

typedef  struct

submax;

#define  neinfinite  (0x80000000)

#define  true      1

#define  false     0

1:最普通的解法,根據定義,求所有子陣列的和,然後找到最大子陣列。時間複雜度為o(n^2)。

從第i個元素開始,連續求得以i為起點,i,i+1,i+2...為終點的子陣列的和,得到以i為起點的所有子陣列的最大值,然後對於i,0

submax normalmaxsub(int *set,  int  num)

for(j = i+1; j < num; j++)

} }

res.max = max;

res.subbegin = begin;

res.subend = end;

return res; }

2:分治演算法:將原陣列分解為左右兩部分,mid為分界點,那麼原陣列的最大子陣列的位置只有3中可能:

a:在mid左邊的子陣列中;

b:在mid右邊的子陣列中;

c:穿過中間節點mid的子陣列。

因找穿過中間節點的最大子陣列的時間複雜度是o(n)。所以,該演算法的時間複雜度:t(n) = 2t(n/2) + o(n),即為o(nlgn)。**如下:

submax  dividemaxsub(int *set,  int  begin,  int  end)

if(begin < end)

if(mid > begin)

midmax = crossmidmaxsub(set, begin, end, mid);

max = (leftmax.max < rightmax.max)?rightmax:leftmax;

max = (max.max < midmax.max)?midmax:max;

return max; }

} submax crossmidmaxsub(int *set,  int  begin,  int  end,  int  mid)

} and = max;

for(j = mid + 1; j <= end; j++)

} res.max = max;

return res; }

3:dp解法,時間複雜度為o(n):

對於陣列

a[0…i]

,若已知它的最大子陣列,如何求

a[0…i+1]

的最大子陣列?

先看陣列

a[0…i],

已知它的最大子陣列,記為

res(i)

,同時,也可求得包含元素

a[i]

的最大子陣列。記為

sum(i)

。對於陣列

a[0…i+1]

,它的最大子陣列,要麼包含元素

a[i+1]

,要麼不包含元素

a[i+1]

:包含元素

a[i+1]

的情況是:

res(i+1)= sum(i+1)

不包含元素

a[i+1]

的情況是

res(i+1)= res(i)

現在的問題就是如何求解sum(i+1):如果sum(i) > 0,則sum(i+1) = sum(i) + a[i+1],否則,sum(i+1) = a[i+1]。

這樣,依次遍歷陣列,每遍歷乙個元素,就可求得sum(i)。具體**如下:

submax  dpmaxsum(int *a, int length)

else

res = (sum > res)?sum:res;

if(res == sum)

} result.max = res;

result.subbegin = resbegin;

result.subend = resend;

return result; }

1:普通的矩陣乘法就是依次掃瞄兩個矩陣的行和列,然後計算結果矩陣的每乙個元素,時間複雜度為

ө(n^3)。

2:分治法求解矩陣的乘積,就是把乙個矩陣依次分為4個部分,對每個部分分別求解。該演算法的遞迴式為:

該演算法的時間複雜度為ө(n^3)。

3:strassen方法:遞迴方法需要8次乘積,strassen

方法採用矩陣的加減法減少了乘機次數,也就是

7次乘積,所以,該演算法的時間複雜度為

ө(n^lg7)。

4:分治模式在每層遞迴時都有三個步驟:

分解:原問題為若干子問題,這些子問題是原問題的規模較小的例項。

解決:這些子問題,遞迴地求解各子問題。然而,若子問題的規模足夠小,則直接求解。

合併:這些子問題的解成原問題的解。

分治演算法執行時間的遞迴式來自基本模式的三個步驟。如前所述,我們假設t(n)是規模為n的乙個問題的執行時間。若問題規模足夠小,如對某個常量c,n≤c,則直接求解需要常量時間,我們將其寫作θ(1)。假設把原問題分解成a個子問題,每個子問題的規模是原問題的1/b。(對歸併排序,a和

b都為2,然而,我們將看到在許多分治演算法中,a≠

b。)為了求解乙個規模為n/b的子問題,需要t(n/b)的時間,所以需要at(n/b)的時間來求解a個子問題。如果分解問題成子問題需要時間

d(n)

,合併子問題的解成原問題的解需要時間

c(n)

,那麼得到遞迴式:

如何求解遞迴式,有3中方法,代入法(先猜測,然後數學歸納法證明),畫遞迴樹(可以猜測結果,然後用代入法求解),主定理。

5:遞迴式主定理:

演算法導論 最大子陣列

之前都在準備考試,寒假還是繼續學習。除了家裡打掃衛生,似乎也確實沒什麼事。多看書,多寫 總能提高的。堅持。這次學到了函式返回值可以是乙個結構體,當我們要返回多個值的時候,就可以返回結構體。還有就是對分治法有了更深的認識。include typedef struct op op findmaxcros...

演算法導論2 最大子陣列

最大子陣列問題 假設陣列a low.high 求存在於陣列a中的連續子陣列之和 或陣列中連續元素之和 最大的子陣列,例如a 4 的最大子陣列為a 0 2 和最大為3 2 1 2。如果採用暴力求解的演算法則問題也可以很簡單的求解出來,不過這種方法的時間複雜度為 n 所以寫一下更好的方法。使用分治策略的...

演算法導論 尋找最大子陣列

求最大子陣列 include using namespace std struct result structure result structure mid array sum int a,int low,int mid,int high sum 0 result.high index mid 1...