最大子陣列,給定陣列,在這個陣列中找到這樣的子陣列:子陣列的和是所有子陣列中最大的(子陣列必須是連續的)。
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...