分治算法例子集锦
描述:
兩部分組成
分(divide):遞歸解決較小的問題?
治(conquer):然后從子問題的解構建原問題的解
三個步驟
1、分解(Divide):將原問題分解為若干個規模較小,相互獨立,與原問題形式相同的子問題;?
2、解決(Conquer):若子問題規模較小而容易被解決則直接解,否則遞歸地解各個子問題;?
3、合并(Combine):將各個子問題的解合并為原問題的解。
四個適用條件
1、該問題的規模縮小到一定的程度就可以容易地解決;?
2、該問題可以分解為若干個規模較小的相同問題,即該問題具有最優子結構性質。?
3、利用該問題分解出的子問題的解可以合并為該問題的解;?
4、該問題所分解出的各個子問題是相互獨立的,即子問題之間不包含公共的子子問題。?
(上述的第一條特征是絕大多數問題都可以滿足的,因為問題的計算復雜性一般是隨著問題規模的增加而增加;第二條特征是應用分治法的前提,它也是大多數問題可以滿足的,此特征反映了遞歸思想的應用;第三條特征是關鍵,能否利用分治法完全取決于問題是否具有第三條特征,如果具備了第一條和第二條特征,而不具備第三條特征,則可以考慮貪心法或動態規劃法。第四條特征涉及到分治法的效率,如果各子問題是不獨立的,則分治法要做許多不必要的工作,重復地解公共的子問題,此時雖然可用分治法,但一般用動態規劃法較好。)
偽代碼表示:
Divide-and-Conquer(P)?
1. if |P|≤n0?
2. then return(ADHOC(P))?
3. 將P分解為較小的子問題 P1 ,P2 ,…,Pk?
4. for i←1 to k?
5. do yi ← Divide-and-Conquer(Pi) △ 遞歸解決Pi?
6. T ← MERGE(y1,y2,…,yk) △ 合并子問題?
7. return(T)
典型實例
求x的n次冪
復雜度為?O(lgn)?的分治算法(c實現)
#include "stdio.h" #include "stdlib.h"int power(int x, int n) {int result;if(n == 1)return x;if( n % 2 == 0)result = power(x, n/2) * power(x, n / 2);elseresult = power(x, (n+1) / 2) * power(x, (n-1) / 2);return result; }int main() {int x = 5;int n = 3;printf("power(%d,%d) = %d \n",x, n, power(x, n)); }- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
歸并排序
http://blog.csdn.net/zwhlxl/article/details/44086683
最大子序列問題
http://blog.csdn.net/zwhlxl/article/details/42649979
參考文章
1、http://raytaylorlin.com/Tech/algorithm/divide-and-conquer/?
2、http://hahack.com/wiki/algorithms-divide-and-conquer.html?
3、http://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741370.html
總結
- 上一篇: 复选框 全选 全不选 反选 实现
- 下一篇: 集群、分布式、负载均衡区别与联系