您好,欢迎访问三七文档
当前位置:首页 > 商业/管理/HR > 创业/孵化 > ACM培训第四讲-递归
ACM程序设计第四讲-递归湖南工学院张新玉zhangxinyu247@163.com算法总体思想•将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。nT(n)=n/2T(n/4)T(n/4)T(n/4)T(n/4)n/2T(n/4)T(n/4)T(n/4)T(n/4)n/2T(n/4)T(n/4)T(n/4)T(n/4)n/2T(n/4)T(n/4)T(n/4)T(n/4)分治法的设计思想是,将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。凡治众如治寡,分数是也。----孙子兵法递归的概念•直接或间接地调用自身的算法称为递归算法。用函数自身给出定义的函数称为递归函数。•由分治法产生的子问题往往是原问题的较小模式,这就为使用递归技术提供了方便。在这种情况下,反复应用分治手段,可以使子问题与原问题类型一致而其规模却不断缩小,最终使子问题缩小到很容易直接求出其解。这自然导致递归过程的产生。•分治与递归像一对孪生兄弟,经常同时应用在算法设计之中,并由此产生许多高效算法。下面来看几个实例。递归例1阶乘函数阶乘函数可递归地定义为:00)!1(1!nnnnn边界条件递归方程边界条件与递归方程是递归函数的二个要素,递归函数只有具备了这两个要素,才能在有限次计算后得出结果。递归例2Fibonacci数列无穷数列1,1,2,3,5,8,13,21,34,55,…,被称为Fibonacci数列。它可以递归地定义为:边界条件递归方程110)2()1(11)(nnnnFnFnF第n个Fibonacci数可递归地计算如下:publicstaticintfibonacci(intn){if(n=1)return1;returnfibonacci(n-1)+fibonacci(n-2);}递归例3Ackerman函数当一个函数及它的一个变量是由函数自身定义时,称这个函数是双递归函数。Ackerman函数A(n,m)定义如下:1,20)1),,1((),(2)0,(1),0(2)0,1(mnnmmmnAAmnAnnAmAA递归例3Ackerman函数前2例中的函数都可以找到相应的非递归方式定义:nnn)1(321!1125125151)(nnnF但本例中的Ackerman函数却无法找到非递归的定义。递归例3Ackerman函数•A(n,m)的自变量m的每一个值都定义了一个单变量函数:•M=0时,A(n,0)=n+2•M=1时,A(n,1)=A(A(n-1,1),0)=A(n-1,1)+2,和A(1,1)=2故A(n,1)=2*n•M=2时,A(n,2)=A(A(n-1,2),1)=2A(n-1,2),和A(1,2)=A(A(0,2),1)=A(1,1)=2,故A(n,2)=2^n。•M=3时,类似的可以推出•M=4时,A(n,4)的增长速度非常快,以至于没有适当的数学式子来表示这一函数。n2222练习•趣味问题——年龄。有5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大?用递归算法实现。2.1递归的概念例4排列问题设计一个递归算法生成n个元素{r1,r2,…,rn}的全排列非递归算法:字典序法[例]字符集{1,2,3},较小的数字较先,这样按字典序生成的全排列是:123,132,213,231,312,321。递归例4排列问题设计一个递归算法生成n个元素{r1,r2,…,rn}的全排列。设R={r1,r2,…,rn}是要进行排列的n个元素,Ri=R-{ri}。集合X中元素的全排列记为perm(X)。(ri)perm(X)表示在全排列perm(X)的每一个排列前加上前缀得到的排列。R的全排列可归纳定义如下:当n=1时,perm(R)=(r),其中r是集合R中唯一的元素;当n1时,perm(R)由(r1)perm(R1),(r2)perm(R2),…,(rn)perm(Rn)构成。递归例5整数划分问题将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,其中n1≥n2≥…≥nk≥1,k≥1。正整数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。(2)q(n,m)=q(n,n),mn;最大加数n1实际上不能大于n。因此,q(1,m)=1。(1)q(n,1)=1,n1;当最大加数n1不大于1时,任何正整数n只有一种划分形式,即nn111(4)q(n,m)=q(n,m-1)+q(n-m,m),nm1;正整数n的最大加数n1不大于m的划分由n1=m的划分和n1≤n-1的划分组成。(3)q(n,n)=1+q(n,n-1);正整数n的划分由n1=n的划分和n1≤n-1的划分组成。递归例5整数划分问题前面的几个例子中,问题本身都具有比较明显的递归关系,因而容易用递归函数直接求解。在本例中,如果设p(n)为正整数n的划分数,则难以找到递归关系,因此考虑增加一个自变量:将最大加数n1不大于m的划分个数记作q(n,m)。可以建立q(n,m)的如下递归关系。11,1),()1,()1,(1),(1),(mnmnmnmnmmnqmnqnnqnnqmnq递归例5整数划分问题前面的几个例子中,问题本身都具有比较明显的递归关系,因而容易用递归函数直接求解。在本例中,如果设p(n)为正整数n的划分数,则难以找到递归关系,因此考虑增加一个自变量:将最大加数n1不大于m的划分个数记作q(n,m)。可以建立q(n,m)的如下递归关系。正整数n的划分数p(n)=q(n,n)。递归例6Hanoi塔问题设a,b,c是3个塔座。开始时,在塔座a上有一叠共n个圆盘,这些圆盘自下而上,由大到小地叠在一起。各圆盘从小到大编号为1,2,…,n,现要求将塔座a上的这一叠圆盘移到塔座b上,并仍按同样顺序叠置。在移动圆盘时应遵守以下移动规则:规则1:每次只能移动1个圆盘;规则2:任何时刻都不允许将较大的圆盘压在较小的圆盘之上;规则3:在满足移动规则1和2的前提下,可将圆盘移至a,b,c中任一塔座上。在问题规模较大时,较难找到一般的方法,因此我们尝试用递归技术来解决这个问题。当n=1时,问题比较简单。此时,只要将编号为1的圆盘从塔座a直接移至塔座b上即可。当n>1时,需要利用塔座c作为辅助塔座。此时若能设法将n-1个较小的圆盘依照移动规则从塔座a移至塔座c,然后,将剩下的最大圆盘从塔座a移至塔座b,最后,再设法将n-1个较小的圆盘依照移动规则从塔座c移至塔座b。由此可见,n个圆盘的移动问题可分为2次n-1个圆盘的移动问题,这又可以递归地用上述方法来做。由此可以设计出解Hanoi塔问题的递归算法如下。递归例6Hanoi塔问题publicstaticvoidhanoi(intn,inta,intb,intc){if(n0){hanoi(n-1,a,c,b);move(a,b);hanoi(n-1,c,b,a);}}课堂练习-基础:•转转相除法求最大公约数课堂练习-题目1:•问题描述:大于1的正整数n可以分解成为n=x1*x2*x3…*xn•例如,当n=12时,共有8种不同的分解式•12=12*1•12=6*2•12=4*3•12=3*412=3*2*2•12=2*612=2*3*212=2*2*3•输入n,求n的整数因子分解2020/1/119•甲、乙两人同时从A地出发要尽快同时赶到B地。出发时A地有一辆小车,可是这辆小车除了驾驶员外只能带一人。已知甲、乙两人的步行速度一样,且小于车的速度。问:怎样利用小车才能使两人尽快同时到达•【输入】•仅一行,三个数据分别表示AB两地的距离s,人的步行速度a,车的速度b。•【输出】•两人同时到达B地需要的最短时间。•【样例】输入:120525输出9.6000000000E+00课堂练习-题目2:今盒子里有n个小球,A、B两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断。我们约定:每个人从盒子中取出的球的数目必须是:1,3,7或者8个。轮到某一方取球时不能弃权!A先取球,然后双方交替取球,直到取完。被迫拿到最后一个球的一方为负方(输方)请编程确定出在双方都不判断失误的情况下,对于特定的初始球数,A是否能赢?课堂练习-题目3:输入:•4•1•2•10•18输出:•0•1•1•0课堂练习-题目3:课后作业•1.完成课上的例题和练习题•2.HDU:•1028,1650,2018,2042,2044•2045,2047,2049,2585,44722020/1/123
本文标题:ACM培训第四讲-递归
链接地址:https://www.777doc.com/doc-2437106 .html