分治算法的思想就是 对于某些特定种类的问题 如果问题的规模很小,那么就直接解决,如果问题的规模比较大,那么就把问题先分解为规模小的但是问题相同的子问题 ,并且不断分解直到规模足够小,再递归地解决这些问题 如果原问题可分割成k个子问题,1<k≤n,且这些子问题都可解并可利用这些子问题的解求出原问题的解,那么这种分治法就是可行的。 递归与分治经常是一起使用的
1.问题复杂性随规模减小而减小
2.问题具有最优子结构性质
最优子结构:如果问题的最优解所包含的子问题的解也是最优的,我们就称该问题具有最优子结构性质(即满足最优化原理)。最优子结构性质为动态规划算法解决问题提供了重要线索。
例如,最短路径问题有以下最优子结构性质:如果一个节点x是到源节点ü的最短路径,同时又是到目的节点V的最短路径,则最短路径从u到v是结合最短路径:u到x和x到v。解决任意两点间的最短路径的算法的Floyd-Warshall算法和贝尔曼-福特是动态规划的典型例子。
3.分解的问题的解可以合并为该问题的解
如果问题不能合就不能用分治,这时可以考虑贪心和动态规划
4.同一个分割级别的各个子问题之间不互相包含 是独立的
Fibonacci 就不是独立的 因为计算 F(9)=F(8)+F(7)时候已经 包含了 F(8)这个子问题 而由于用的是递归的思想 ,所以 F(8) 会被重复计算,效率不高 子问题互相重叠应该考虑用动态规划
很多书都有介绍了 步骤就是:
1.分解 2.解决 3.合并
step1 分解:将原问题分解为若干个规模较小,相互独立,与原问题形式相同的子问题;
step2 解决:若子问题规模较小而容易被解决则直接解,否则递归地解各个子问题
step3 合并:将各个子问题的解合并为原问题的解。
二分搜索
大整数乘法
Strassen矩阵乘法
棋盘覆盖
mergesort 归并排序
快速排序
线性时间选择
最接近点对问题
循环赛日程表
汉诺塔
依据分治法设计程序时的思维过程
1 /************************************************************************* 2 > File Name: mergesort.cpp 3 > Author: VOID_133 4 > Created Time: 2014年08月06日 星期三 14时17分16秒 5 > Content : Divide and Conquer Classic Problem 6 MergeSort 7 ************************************************************************/ 8 9 #include<iostream> 10 #include<cstdio> 11 using namespace std; 12 const int MAX=100000; 13 int L[MAX]; 14 int R[MAX]; 15 void mergesort(int* A,int first,int end); 16 void merge(int *A,int first,int mid,int end); 17 void mergesort(int* A,int first,int end) 18 { 19 if(first<end) 20 { 21 int mid=(first+end)/2; 22 mergesort(A,first,mid); 23 mergesort(A,mid+1,end); //Solve the problem recursively 24 merge(A,first,mid,end); 25 } 26 return ; 27 } 28 29 void merge(int *A,int first,int mid,int end) 30 { 31 int lenL=mid-first+1; 32 int lenR=end-mid; 33 for(int i=1;i<=lenL;i++) L[i]=A[first+i-1]; 34 for(int i=1;i<=lenR;i++) R[i]=A[mid+i]; 35 int li=1; 36 int ri=1; 37 int cnt=first; //the array we should merge is from A[first] to A[end] so we can only modify these value ,we shouldn‘tmodify other A values 38 //The Problem has fixed 39 while(li<=lenL && ri <=lenR) 40 { 41 int tmp; 42 if(L[li]>R[ri]) 43 { 44 tmp=R[ri]; 45 ri++; 46 } 47 else 48 { 49 tmp=L[li]; 50 li++; 51 } 52 A[cnt++]=tmp; 53 } 54 while(li<=lenL) 55 { 56 A[cnt++]=L[li++]; 57 } 58 while(ri<=lenR) 59 { 60 A[cnt++]=R[ri++]; 61 } 62 return ; 63 } 64 65 66 int main(void) 67 { 68 int arr[MAX]; 69 int n; 70 while(scanf("%d",&n)!=EOF && n) 71 { 72 for(int i=1;i<=n;i++) cin>>arr[i]; 73 mergesort(arr,1,n); 74 for(int i=1;i<=n;i++) cout<<arr[i]<<" "; 75 cout<<endl; 76 } 77 return 0; 78 }
分治算法学习 Divide and Conquer,布布扣,bubuko.com
原文:http://www.cnblogs.com/VOID-133/p/3893939.html