递归算法及用递归求解整数的分划问题

一、递归的概念

递归(recursion)是一个过程或函数在其定义或说明中又直接或间接调用自身的一种方法。一般为了处理重复性的操作,都采用递归的办法来实现。

二、递归算法设计

递归算法设计,就是把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题.在逐步求解小问题后,再返回(回溯)得到大问题的解。递归算法只需少量的步骤就可描述出解题过程所需要的多次重复计算,大大地减少了算法的代码量。
递归算法设计的关键在于找出递归关系(方程)和递归终止(边界)条件。递归关系就是使问题向边界条件转化的规则。递归关系必须能使问题越来越简单,规模越来越小。递归边界条件就是所描述问题最简单的、可解的情况,它本身不再使用递归的定义。

三、递归算法解题步骤

  1. 分析问题、寻找递归关系:找出大规模问题与小规模问题的关系,这样通过递归使问题的规模逐渐变小。
  2. 设置边界控制递归:找出停止条件,即算法可解的最小规模问题。
  3. 设计函数、确定参数:和其他算法模块-样设计 函数体中的操作及相关参数。

四、递归设计例题——>整数的分划问题

1. 问题描述

对于一个正整数n的分划就是把n写成一系列正整数之和的表达式。注意,分划与顺序无关,例如6=5+1和6=1+5被认为是同一种分划。另外,这个整数n本身也算是一种分划。
例如: 对于正整数n=6,他可以分划为:
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

2. 建立递归分划数目的递归公式

根据例子发现“包括第一行以后的数据不超过6,包括第二行的数据不超过5,……,第六行的数据不超过1”。因此,定义一个函数Q(n,m),表示整数n的“任何被加数都不超过m”的分划的数目,n的所有分划的数目P(n)=Q(n,n)。

模型的建立:

一般地Q(n.m)有以下递归关系:
(1)Q(n,n)=1+Q(n,n-1) (m=n)
Q(n,n-1)表示n的所有其他分划,即最大被加数m<=n-1的划分。
(2)Q(n,m)=Q(n,m-1)+Q(n-m,m) (m<n)
Q(n,n-1)表示被加数中不包含m的分划的数目;
Q(n-m,m)表示被加数中包含(注意不是小于)m的分划的数目

递归停止的条件:

(1)Q(n,1)=1,表示当最大的被加数是1时,该整数n只有一种分划,即n个1相加;
(2)Q(1,m)=1,表示整数n=1只有一个分划,不管最大被加数的上限m是多大。

3. 递归算法的设计(伪码描述)

main()
{
    int n;
    input(n);
    if(n<1) 
    {
        Error("输入参数错误!");
    }
    Divinteger(n,n);
}
Divinteger(int n,int m)
{
    if(n=1 or m=1) 
    {
        return 1;
    } else if(n<m) {
        return Divinteger(n,n);
    } else if(n=m) {
        return 1+Divinteger(n,n-1);
    } else
        return Divinteger(n,m-1)+Divinteger(n-m,m);;
}

4. 算法说明

由于算法中,多次进行递归调用,正整数分化的数目随着n的增加增长的非常快,大约是以指数级增长,所以此算法不适合对较大的整数进行划分。但是可以继续对其进行优化——用回溯递归的算法对其进行更高级的算法设计。

发布了28 篇原创文章 · 获赞 13 · 访问量 457

猜你喜欢

转载自blog.csdn.net/yo_u_niverse/article/details/105453716