递推-递归-分治-回溯.docVIP

  • 20
  • 0
  • 约2.24万字
  • 约 23页
  • 2017-10-03 发布于重庆
  • 举报
递推-递归-分治-回溯

递推算法 在程序编辑过程中,我们可能会遇到这样一类问题,出题者告诉你数列的前几个数,或通过计算机获取了数列的前几个数,要求编程者求出第N项数或所有的数列元素(如果可以枚举的话),或求前N项元素之和。这种从已知数据入手,寻找规则,推导出后面的数的算法,称这递推算法。 典型的递推算法的例子有整数的阶乘,1,2,6,24,120…,a[n]=a[n-1]*n(a[1]=1);前面学过的2n,a[n]=a[n-1]*2(a[1]=1),菲波拉契数列:1,2,3,5,8,13…,a[n]=a[n-1]+a[n-2](a[1]=1,a[2]=2)等等。 在处理递推问题时,我们有时遇到的递推关系是十分明显的,简单地写出递推关系式,就可以逐项递推,即由第i项推出第i+1项,我们称其为显示递推关系。但有的递推关系,要经过仔细观察,甚至要借助一些技巧,才能看出它们之间的关系,我们称其为隐式的递推关系。 下面我们来分析一些例题,掌握一些简单的递推关系。 例如阶梯问题:题目的意思是:有N级阶梯,人可以一步走上一级,也可以一步走两级,求人从阶梯底走到顶端可以有多少种不同的走法。 这是一个隐式的递推关系,如果编程者不能找出这个递推关系,可能就无法做出这题来。我们来分析一下:走上第一级的方法只有一种,走上第二级的方法却有两种(两次走一级或一次走两级),走上第三级的走法,应该是走上第一级的方法和走上第二级的走法之和(因从第一级和第二级,都可以经一步走至第三级),推广到走上第i级,是走上第i-1级的走法与走上第i-2级的走法之和。很明显,这是一个菲波拉契数列。到这里,读者应能很熟练地写出这个程序。在以后的程序习题中,我们可能还会遇到菲波拉契数列变形以后的结果:如f(i)=f(i-1)+2f(i-2),或f(i)=f(i-1)+f(i-2)+f(i-3)等。 我们再来分析一下尼科梅彻斯定理任何一个整数的立方都可以写成一串连续的奇数和,如:…时,则输出恰好为连续奇数,1,3,5,7,9,11…即下一行的首项比上一行的末项大2。 经上面的分析,原本看不出递推关系的问题,呈现出递推关系。在趣的是,这个例子的递推过程,可以有多种算法。 算法一:将所有奇数逐项例举出来,然后将其分段,即: 1; 3 5; 7 9 11; 13 15 17 19; 21… 1 2 3 4 5… 算法二、设输入为n时的输出第一项为a[n],则a[n]=a[n-1]-n+1; 于是我们推出首项后,则输出为a[n]+a[n]+2+…+a[n]+2(n-1) 算法三、进一步总结,不难得出,若输入为n时,首项a[n]=n2-n+1,其余同算法二。下面我们来分析两个与动物有关的趣题。 这个题目中,读者不难理解,如果狼每次都能走入一个以前没有到过的洞中,则无论兔子怎么躲藏,都不能幸免遇狼。若狼跳越若干次后,不仅走到了以前到过的洞中,而且要跳越的洞数又与以前的某次相同,则狼就会循环往复地在同一些洞中跳来跳去,成为小丑而无法跳入以前没有到过的洞中。这些洞恰恰就是兔子的安全洞穴。 基于以上的分析,兔子有安全洞穴的条件有三,一是狼经过若干次跳跃后,回到原来到过的洞中;二是同一洞历史上的某一次跳越的洞数与即将要跳的这一次跨越的洞数也相同;三是到此时为止,狼应有从未到过的洞穴。 基本的算法是:从1号洞开始,按11-32-63-104-45-106-……方式,由前一个状态推导出下一个状态,同时将每一个新状态与前面存贮下来的状态作比较,以便找到两个可以作结论的状态。即要么狼已走遍了所有兔子洞,要么狼卷入死循环,而有些洞无法进入。 那么,现在我们怎样来存贮这些状态呢?最简单的办法是计数。 我们对每个洞建立一个数组,用来记载这个洞狼是否到过,在这个洞中跳越洞数,以及狼所经历过的新洞数。程序的关键部分如下,其余部分请读者完善。 program ex02; var a:array[1..n,0..10] of 0..1; t:integer; j:integer; s:integer; begin fillchar(a,sizeof(a),0); t:=1; j:=1; a[t,j]:=1; s:=1; repeat t:=t+j+1; if tn then t:=t mod n; if a[t,j]=1 then break; j:=j+1; if j10 then j=1; if a[t,0]=0 then inc(s); until (s=n) if s=n then write(0) else for k:=1 to n do if a[k,0]=0 the

文档评论(0)

1亿VIP精品文档

相关文档