递归与分治策略

一. 基本思想

分治法的基本思想是,将一个难以直接解决的大问题,分割成一些规模较小的子问题,这些子问题互相独立且与原问题相同。递归地解这些子问题,然后将各子问题的解合并得到原问题的解。(分-治-合)

二. 适用条件

分治法所能解决的问题一般具有以下几个特征:

  • 该问题的规模缩小到一定的程度就可以容易地解决;
  • 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质(当问题的最优解包含了其子问题的最优解时,称该问题具有最优子结构性质);
  • 分解出的子问题的解可以合并为原问题的解;
  • 分解出的各个子问题是相互独立的。

三. 基本步骤

divide-and-conquer(P)
{
	if ( |P| <= n0 ) { y= adhoc(P);  return y; }	//解决小规模的问题
        else
	{
		divide P into smaller subinstances P1,P2,...,Pk; //分解问题
		for (i=1,i<=k,i++)
			yi=divide-and-conquer(Pi);  //递归的解各子问题
		return merge(y1,...,yk);	//将各子问题的解合并为原问题的解
	}
}

在用分治法设计算法时,最好使子问题的规模大致相同。即将一个问题分成大小相等的k个子问题的处理方法是行之有效的。这种使子问题规模大致相等的做法是出自一种平衡(balancing)子问题的思想。

四. 复杂性分析

一个分治法将规模为n的问题分成k个规模为n/m的子问题去解。设分解阀值n0=1,且adhoc解规模为1的问题耗费1个单位时间。再设将原问题分解为k个子问题以及用merge将k个子问题的解合并为原问题的解需用f(n)个单位时间。用T(n)表示该分治法解规模为|P|=n的问题所需的计算时间,则有:

通过迭代法求得方程的解:

时间: 2024-10-11 11:31:16

递归与分治策略的相关文章

递归与分治策略(一)---算法设计与分析

递归与分治策略(一) 简而言之,递归就是自己调用自己. 递归算法:直接或者间接地调用自身的算法. 递归函数:用函数自身给出定义的函数. 注意:每个递归函数都必须有非递归定义的初始值,以确保递归函数完成计算. 下面通过两个例子来介绍递归的特点 例1 阶乘函数 阶乘函数递归地定义为: n!=1   (n=0) 或者 n!=n(n-1)!  (n>0) 下面用一段简单的Java代码实现 这里是递归实现: public static int facterial(int n) { if (n == 0)

计算机算法设计与分析之递归与分治策略——二分搜索技术

递归与分治策略 二分搜索技术 我们所熟知的二分搜索算法是运用分治策略的典型例子,针对这个算法,先给出一个简单的案例. 目的:给定已排好序的n个元素a[0:n-1],现要在这n个元素中找出一特定的元素x. 我们首先想到的最简单的是用顺序搜索方法,逐个比较a[0:n-1]中元素,直至找出元素x或搜索遍整个数组后确定x不在其中.这个方法没有很好地利用n个元素已排好序的这个条件,因此在最坏的情况下,顺序搜索方法需要O(n)次比较. 而二分搜索方法充分利用了元素间的次序关系,采用分治策略,可在最坏情况下用

算法分析之递归与分治策略

递归与分治策略 直接或间接地调用自身的算法称为递归算法.用函数自身给出定义的函数称为递归函数. 在计算机算法设计与分析中,使用递归技术往往使函数的定义和算法的描述简洁且易于理解. 例1 阶乘函数 可递归地定义为:其中:n=0 时,n!=1为边界条件n>0 时,n!=n(n-1)!为递归方程边界条件与递归方程是递归函数的二个要素,递归函数只有具备了这两个要素,才能在有限次计算后得出结果. 例2 Fibonacci数列无穷数列1,1,2,3,5,8,13,21,34,55,…,被称为Fibonacc

五大常见算法策略——递归与分治策略

摘要:递归与分治策略是五大常见算法策略之一,分治策略的思想就是分而治之,即先将一个规模较大的大问题分解成若干个规模较小的小问题,再对这些小问题进行解决,得到的解,在将其组合起来得到最终的解.而分治与递归很多情况下都是一起结合使用的,能发挥出奇效(1+1>2),这篇文章我们将先从递归说起,再逐渐向分治过渡,主要讲解方式是通过9个例题来说明问题的,问题都是根据难度由简到难,由浅入深,对递归与分治能有个大概的了解雏形,当然最重要还是要做大量练习才能掌握. 1.递归 我们第一次接触递归一般都是在初学C语

算法设计与分析笔记(一)递归与分治策略

一>递归:直接或间接地调用自身的算法. EG: 1>阶乘定义 n!=n(n-1)! (n>0); pubic static int factorial(int n ){ if(n==0) return 1; else return n*factorial(n-1); } 2>FiBonacci数列 public static int fibo(int n){ if(n<=1)return 1; else fibo(n-1)+fibo(n-2); } 3>排列问题(一个集

第二章-递归与分治策略

第一题: 问题名称:整数划分问题. 问题描述:正整数n可以表示为一系列正整数之和:n = n1 + n2 + ... + nk (k>=1, n1>=n2>=nk ),则称这种表示为正整数n的划分,不同的这种表示的个数称为正整数n的划分数,记为p(n).在所有划分中,将最大加数n1不大于m的划分数,记为q(n,m). 问题分析: q(n, m) =  1 ,当n = 1,m = 1;   q(n,n) ,当n < m: 1 + q(n,n-1),当n = m: q(n,m-1) +

[图解算法] 线性时间选择——//递归与分治策略//【图解才是最直观】

1 #include <ctime> 2 #include <iostream> 3 using namespace std; 4 5 template <class Type> 6 void Swap(Type &x,Type &y); 7 8 inline int Random(int x, int y); 9 10 template <class Type> 11 void BubbleSort(Type a[],int p,int r

2.6 递归与分治策略(汉诺塔问题)

汉诺塔问题是一个经典问题. 题意理解:有A,B,C三个柱子,将A柱子上的N个盘子(从小到大排列)移到C柱子上,每次只允许移动一个盘子,并且保证每个柱子上的盘子的排列都是从小到大. 分析:由题意可知,如果要将A上的盘子移动到C,那么肯定需要借助C. 首先将A上的盘子从上到下依次编号为1-n. 运用整体思想: 1.假设1到n-1个盘子是一个整体 2.将1到n-1个盘子构成的整体移动到B 3.将第n个盘子移动到C 4.再将第2步移动到B的整体移动到C就可以了. 重复以上过程,显然这是一个递归的过程.下

2_3 递归与分治策略(二分搜索技术)

二分搜索算法是分支策略的典型应用,具体是在给定的有n个元素的已排序序列a中找出一个特定元素. 基本思想:将n个元素分为两半,取a[n/2]与x进行比较, 如果x<a[n/2],继续在数组a的左半部分搜索. 如果x>a[n/2],继续在数组a的右半部分搜索. (图片源自百度图片) 查找算法对比: 1.顺序搜索不能很好利用排序这个已知条件,而且是O(n)算法. 2.二分搜索充分利用排序条件,算法复杂度是O(log n). 上代码: public class a_2_3<T extends C