005-算法-分治法

一、概念: 在计算机科学中,分治法是建基于多项分支递归的一种很重要的算法范式。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,直到最后子问题可以寄简单的直接求解,原问题的解即子问题的解的合并。

这个技巧是很多高校算法的基础,如排序算法(快速排序、归并排序)、傅立叶转换(快速傅立叶变换)

思路:

1.分解:把原问题分解为若干个规模较小,相对独立,与原问题形式相同的子问题。

2. 解决:若子问题规模较小且易于解决时,则直接解。否则,递归地解决各子问题。

3.合并:讲各子问题的解合并为原问题的解。

分治算法是按照下列方案来工作的:

1)将问题的实例划分为几个较小的实例,最好具有相等的规模(事实上,一般来说就是这样来分的,而且分为2个实例的居多,注意是递归的分!!!)

2)对这些较小的实例求解(一般使用递归的方法,但在问题规模足够小的时候也可以采用采用另一个算法(停止递归))

3)如果有必要的话,合并这些较小问题的解,以得到原始问题的解(事实上,一个分治算法的精华就在于合并解的过程)

不要忽视这三句话!!!它是许多分治算法经验的总结,有助于在分析问题中考虑如何去使用分治算法,提请注意括号里我的注释!!!

形象的表示一下,截张图:

  

参照:http://www.cnblogs.com/kkgreen/archive/2011/06/10/2077923.html

总结:

1)分治的思想:一般递归来实现,划分子问题,合并子问题的解。

2)主定理,要很熟悉,常见的递推式应该一眼判断其复杂度。

3)合并排序,快速排序,折半查找,二叉遍历树相关特性,这些都是数据结构的经典内容,之前也都写过了,代码参见前面的相关文章。

这里再次复习,从不同的视角来看它们都是如何用用到了分治的策略。这些内容应当非常熟练。

005-算法-分治法

时间: 2024-10-11 03:08:33

005-算法-分治法的相关文章

算法---分治法

1.分治法的思想: 将一个输入规模为n的问题分解为k个规模较小的子问题,这些子问题互相独立且与原问题相同,然后递归的求解这些子问题,最后用适当的方法将各子问题的解合并成原问题的解. 2.分治法的步骤: 分(divide) 二分为主 治(conquer) 递归调用,当规模足够小时直接处理 组(combine) 3.抽象化控制 procedure DANDC(p,q) global n, A(1:n); integer m, p, q; //1≤p≤q≤n// if SMALL(p,q) //判断输

基础算法 分治法之合并排序

思想: 合并排序算法的分治策略是将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最终将排好序的子集合合并成所要求的排好序的集合. 1 #include <stdio.h> 2 3 void merge(int a[],int p,int q,int r) 4 { 5 int n1=q-p+1,n2=r-q; 6 int b1[n1]; 7 int b2[n2]; 8 int i=0,j=0,temp1=p,temp2=q; 9 while(p<=q) 10 { 11

初学算法-分治法求平面上最近点对(Closest Pair)-HDU 1007

本来这个算法在笔者电脑里无人问津过一段时间了,但今天正好做HDU 1007见到了这个问题,今天就来把代码分享出来吧! 我们首先将所有点按照坐标x排序一下,再做一条直线l当作"分割线",方便我们递归. 然后,我们就可以把这些点按照x轴的坐标分为左半部分和右半部分.那么最短距离一定在左半部分.右半部分.跨越左右的点对中的一个. 那么你可能会有疑问了:本来最近点对也一定在这三个区域内,这不还是相当于什么都没干吗? 还真不是.我们可以假设通过递归得到了左边最小距离为d1,右边最小距离为d2,令

基础算法 分治法求最大最小元

思路:运用分治的思想,将要排序的整个数组从中间劈开,分别求其左右两边的最大最小值,然后将求出的最大最小值合起来进行比较. 当左右两边的数组小到一定程度时: (1)数组中只有一个元素,maxNum=minNum; (2)数组中有两个元素,找出两个元素中的最大最小值; (3)数组中大于两个元素,从中间分开,继续递归; 1 #include<stdio.h> 2 #include<iostream> 3 #include<stdlib.h> 4 using namespace

算法复习笔记(分治法、动态规划、贪心算法)

分治法 动态规划 贪心算法 分治法 分治法的基本思想是将一个规模为n的问题分解为k个规模较小的问题,这些子问题互相独立且与原问题相同(所以可以递归).递归地解这些子问题,然后将各个子问题的解合并得到原问题的解.它的一般算法设计模式如下: divide-and-conquer(P) { //|P|表示问题的规模,n0表示阈值,当规模不超过n0时,问题容易解出,不必分解 if(|P|<=n0) adhoc(P); //将P分解成子问题 divide P into smaller subinstanc

算法实验:分治法合并排序(C++)

这篇文章分两部分来写,第一部分写代码的实现过程,第二部分把实验报告从头到尾呈现出来. 我习惯调试使用的编译器是DEV C++,不是vs系列的,可能头文件上有点区别.但是下面的报告是我放到vs里面测试过的,可以直接用,不影响. 第一部分:(解析) 题目:随机产生一个整型数组,然后用合并排序将该数组做升序排列,要求输出排序前和排序后的数组. 题目分析: 需要随机产生一个整数数组: 采用的算法是合并排序,也就是用归并排序: 输出排序后的数组. 随机产生一个整数数组:这个问题首先想到的是用rand()函

动态规划和分治法,贪心算法以及递归的再一次深刻理解和体会

每次体会算法都有新的感觉,刷题越多,对算法的理解感觉也就越深刻. 下面我们来重新体会下分治法,动态规划,贪心法,递归的理解. 1.分治法: 将问题分成单独的阶段,每个阶段互相不干扰很独立,如10米长的木棍,切成10段,每段去解决每一段的问题.(阶段没有关系) 2.贪心法 站在全局的角度,也是将问题堪称分为多个阶段,只不过阶段和阶段之间有一定的递进关系,如从5毛,1元,2毛,1毛,2元中,去找最少的钱币构成10块钱.首先是站在全局的角度,先从中取其最大值,为第一阶段,然后在从剩余的当中在找最大值,

算法(二)--------分治法

分治法的适?条件: • 该问题的规模缩?到?定程度就可以容易地解决.• 该问题可以分解为若?个规模较?的相同问题:递归思想的应?• 该问题所分解出的各个?问题是相互独?的,即?问题之间不包含公共的?问题.• 利?该问题分解出的?问题的解可以合并为该问题的解. 案例---快排: (1)过程 • Divide (Partition) – 对元素进?重排以得到这样?个划分 • 在某个位置s前?的所有元素都?于等于A[s] • 在位置s后?的所有元素都?于等于A[s]• Conquer: ?个划分确定后

算法设计《分治法》归并排序(三)实例分析之逆序对数

问题定义: 假设A[1...n]是一个有n个不同数的数组.若i<j且A[i]>A[j]则称(A[i], A[j])为数组A的一个逆序对. 例如数组<2, 3, 8, 6, 1>有(2, 1),(3, 1),(8, 6),(8, 1)和(6,1)5个逆序对. 对于这个问题,直观上进行求解的话,使用暴力求解的方式的话,对于每个数num,都遍历数组中num后的所有数的话,则时间复杂度为O(n^2). 实现代码如下: 另一种方式,便是使用分治法,首先将整个数组分成两部分,然后,分别求解两个

分治法、动态规划、回溯法、分支界限法、贪心算法

转:http://blog.csdn.net/lcj_cjfykx/article/details/41691787 分治算法一.基本概念 在计算机科学中,分治法是一种很重要的算法.字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并.这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求解的问题所需的计算时