递归与分治策略

1. 递归的概念

例1 阶乘函数

n ! = {   1 n = 0 n ( n − 1 ) ! n > 0 n! = \begin{cases} \ 1 & n=0 \\ n(n-1)! & n>0 \\ \end{cases} n!={ 1n(n1)!n=0n>0
其中 n = 0 n=0 n=0是边界条件, n ( n − 1 ) ! n > 0 n(n-1)! n>0 n(n1)!n>0是递归方程,这是递归函数的两个要素。

例2 Fibonacci数列

F ( n ) = {   1 n = 0 1 n = 1 F ( n − 1 ) + F ( n − 2 ) n > 1 F(n) = \begin{cases} \ 1 & n=0 \\ 1 & n=1 \\ F(n-1)+F(n-2) & n>1 \\ \end{cases} F(n)= 11F(n1)+F(n2)n=0n=1n>1

例3 整数划分问题
将正整数n表示成一系列正整数之和: n = n 1 + n 2 + . . . + n k n=n_{1}+n_{2}+...+n_{k} n=n1+n2+...+nk,其中 n 1 ⩾ n 2 ⩾ . . . ⩾ n k ⩾ 1 , k ⩾ 1 n_{1} \geqslant n_{2} \geqslant ... \geqslant n_{k} \geqslant 1,k\geqslant 1 n1n2...nk1,k1
正整数 n n n的这种表示称为正整数n的划分。求正整数 n n n的不同划分个数。

例如正整数6有如下11种不同的划分:

6;
5+1;
4+2,4+1+1;
3+3,3+2+1,3+1+1+1;
2+2+2,2+2+1+1,2+1+1+1+1;
1+1+1+1+1+1.

p ( n , m ) p(n,m) p(nm)为最大加数 n 1 n_{1} n1不大于 m m m的划分个数,则

(1) q ( n , 1 ) = 1 , n ⩾ 1 ; q(n,1)=1,n \geqslant 1; q(n,1)=1,n1;
当最大加数 n 1 n_{1} n1不大于1时,任何正整数只有一种划分形式,即
n = 1 + 1 + 1 + ⋯ + 1 ⏞ n n=\overbrace{1+1+1+\cdots+1}^{\rm n} n=1+1+1++1 n
(2) q ( n , m ) = q ( n , n ) , m ⩾ n ; q(n,m)=q(n,n),m\geqslant n; q(n,m)=q(n,n),mn;
最大加数 n 1 n_{1} n1实际上不能大于n。因此, q ( 1 , m ) = 1 。 q(1,m)=1。 q(1,m)=1
(3) q ( n , n ) = 1 + q ( n , n − 1 ) ; q(n,n)=1+q(n,n-1); q(n,n)=1+q(n,n1);
正整数 n n n的划分由 n 1 = n n_{1}=n n1=n的划分和 n 1 ⩽ n − 1 n_{1}\leqslant n-1 n1n1的划分组成。
(4) q ( n , m ) = q ( n , m − 1 ) + q ( n − m , m ) , n > m > 1 ; q(n,m)=q(n,m-1)+q(n-m,m),n>m>1; q(n,m)=q(n,m1)+q(nm,m),n>m>1;
正整数 n n n的最大加数 n 1 n_{1} n1不大于 m m m的划分由 n 1 = m n_{1}=m n1=m的划分和 n 1 ⩽ m − 1 n_{1}\leqslant m-1 n1m1的划分组成。
由此可以得到:
q ( n , m ) = {   1 n = 1 , m = 1 q ( n , n ) n < m 1 + q ( n , n − 1 ) n = m q ( n , m − 1 ) + q ( n − m , m ) n > m > 1 q(n,m) = \begin{cases} \ 1 & n=1,m=1 \\ q(n,n) & n<m \\ 1+q(n,n-1) & n=m \\ q(n,m-1)+q(n-m,m) &n>m>1\\ \end{cases} q(n,m)= 1q(n,n)1+q(n,n1)q(n,m1)+q(nm,m)n=1,m=1n<mn=mn>m>1
正整数 n n n的划分数 p ( n ) = q ( n , n ) . p(n)=q(n,n). p(n)=q(n,n).

例4 Hanoi塔
把盘子1~n由A移动到C,分三个阶段:

  1. 把盘子1~n-1由A移动到B
  2. 把盘子n由A移动到C
  3. 把盘子1~n-1由B移动到C

在这里我们把盘子1~n-1的移动看作一个整体移动

2.分治法

总体思想:将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。
由分治法产生的子问题往往是原问题的较小模式,使用递归技术,使子问题与原问题类型一致而其规模却不断缩小。
分治法的适用条件

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

  • 该问题的规模缩小到一定的程度就可以容易地解决;
  • 该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质;
  • 利用该问题分解出的子问题的解可以合并为该问题的解。

3.二分搜索技术

二分搜索算法是运用分治策略的典型例子。给定已排好序的n个元素a[0:n-1],现要在这n个元素中找出一特定元素x。
基本思想是,将n个元素分成个数大致相等的两半,取a[n/2]与x作比较。如果x=a[n/2],则找到x,算法终止;如果x<a[n/2],则只在数组a的左半部继续搜索x;如果x>a[n/2],则只在数组a的右半部继续搜索x。

4.棋盘覆盖

在一个 2 k × 2 k ( k ⩾ 0 ) 2^{k}\times 2^{k}(k\geqslant 0) 2k×2kk0个方格组成的棋盘中,恰有一个方格与其他方格不同,称该方格为特殊方格,显然,特殊方格在棋盘中出现的位置有 4 k 4^{k} 4k种不同的情形,因而有 4 k 4^{k} 4k种不同的棋盘。
在棋盘覆盖问题中,需要用4种不同形态的L型三格骨牌覆盖一个给定的特殊棋盘上除特殊方格以外的所有方格,且任何2个L型骨牌不得重复覆盖。易知,在任何一个 2 k × 2 k 2^{k}\times 2^{k} 2k×2k的棋盘覆盖中,用到的L型骨牌个数恰为 ( 4 k ) / 3 (4^{k})/3 (4k)/3
(1)当k>0时,将 2 k × 2 k 2^{k}\times 2^{k} 2k×2k棋盘分割为4个 2 k − 1 × 2 k − 1 2^{k-1}\times 2^{k-1} 2k1×2k1子棋盘
(2)用一个L型骨牌覆盖这3个较小棋盘的结合处

5.合并排序

将待排序元素分成大小大致相同的两个子集合,分别对两个子集合进行排序,最终将排好序的子集合合并成要求的排好序的集合。时间复杂度是o(nlogn)

6.快速排序

快速排序是一种基于划分的排序方法;
划分:选取待分类集合A中的某个元素t,按照与t的大小关系重新整理A中元素,使得整理后的序列中所有在t以前出现的元素均小于等于t,而所有在t以后的元素均大于等于t。这一元素的整理过程称为划分。元素t称为划分元素。
算法过程:设要排序的数组是A[0]…A[N-1],首先任意选取一个数据(通常选用第一个数据)作为关键数据,然后将所有比它小的数都放到它前面,所有比它大的数都放到它后面,这个过程称为一趟快速排序。

7.选择问题

选最大: 顺序比较
选最大和最小: 分组算法
分组算法:

  1. 将n个元素两两一组分成 ⌊ n / 2 ⌋ \lfloor n/2\rfloor n/2
  2. 每组比较,得到 ⌊ n / 2 ⌋ \lfloor n/2\rfloor n/2个较小和 ⌊ n / 2 ⌋ \lfloor n/2\rfloor n/2个较大
  3. ⌈ n / 2 ⌉ \lceil n/2\rceil n/2个较大(含轮空元素)中找最大max
  4. ⌈ n / 2 ⌉ \lceil n/2\rceil n/2个较小(含轮空元素)中找最小min

选第二大: 顺序比较、锦标赛算法
锦标赛算法:

  1. 两两分组比较,大者进入下一轮,直到剩下1个元素max为止
  2. 在每次比较中淘汰较小元素,将被淘汰元素记录在淘汰它的元素的链表上
  3. 检查max的链表,从中找到最大元,即second

选第k小: 1.调用k次选最小算法;2.先排序,然后输出第k小的数
分治算法:

  1. 将n个元素分为 ⌈ n / 5 ⌉ \lceil n/5\rceil n/5组,每组按从大到小的顺序排好
  2. 将每组中间元素按从小到大的顺序排好,中间元素移动时其余元素也跟着移动
    最终结果如图所示:

    若A的组数为r组,则A中元素为2r,B中元素为3r+2,C中元素为3r+2,D中元素为2r。这样可以根据k的大小选择对应的区。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值