加载中…
个人资料
  • 博客等级:
  • 博客积分:
  • 博客访问:
  • 关注人气:
  • 获赠金笔:0支
  • 赠出金笔:0支
  • 荣誉徽章:
正文 字体大小:

第三节   层层递进——递推法与迭代法

(2011-10-22 20:46:03)
标签:

杂谈

分类: QBASIC教程

第三节   层层递进——递推法与迭代法

           

1.熟悉递推法和迭代法的思路;

2.能够用递推法和迭代法解决数列问题。

 

在数学中我们常常会遇到这样的问题:已知第

一项(或几项),要求能得出后面项的值,这就

是用了一种叫递推的方法。

 

【学习任务9有个爱好幻想的人,想知道一年内一对兔子能繁殖多少对小兔子。于是,他围了一个栅栏,把一对刚出生并且是雌雄成对的小兔子养在里面。假设小兔子生下后第二个月就能繁殖,以后每月生产一次且每次都是生一雌一雄两只兔子,那么一年后将有多少对兔子?假设没有兔子死亡。

这是一道有趣的数学题,也就是著名的意大利数学家斐波那契在算盘书中记载的兔子问题

v    【问题分析

v    1个月,有一对小兔子;

v    2个月,小兔子长成了大兔子;

v    3个月,大兔子;生下一对小兔子,这时,有2对兔子了;

v    4个月,大兔子又生了一对小兔子,小兔子也长成大兔子了,栅栏里有3对兔子;

v    5个月,原来大兔子又生了一对小兔子,而第3个月出生的兔子已成熟,也生了一对小兔子,这时共有5对兔子;

v    ……

v    以此类推,我们可以用如图10-2来表示(B为一对小兔子,A为一对大兔子)

 

v    数量                月数

v                           B                          1                 1个月

v                                                

v                           A                          1                 2个月

v           

v                       A      B                      2                 3个月    

v  
                A      B       A                 3                 4个月 

v  
            A      B     A   A    B           5                 5个月

v  
        A     B      A A  B A  B    A     8                 6个月

v                               兔子繁殖说明图

 

v   从图解分析来看,很容易得出兔子繁殖的规律:

v    1123581321345589144……

v    由此可知,一对刚出生的兔子,经过一年可以繁殖成144对兔子。观察上面的数列不难发现,从第3项开始,每个数都是紧邻的前面两个数的和,这样的数列就是有名的斐波那契数列。

v   斐波那契数列的规律是:数列中的第1及第2个数是1,从第3个数起,该数是其前面2个数之和。我们可以编写程序输出此数列的前20项。

 

v     【程序清单

v     REM L10 -12A

v     CLS

v     f1 = 1

v     f2 = 1

v     PRINT f1, f2,

v     FOR i = 3 TO 20

v           f3 = f1 + f2

v           PRINT f3,

v           f1 = f2

v           f2 = f3

v     NEXT i

v     PRINT

v     END

v     【运行结果

v     1            1             2             3             5

v     8            13           21           34           55

v     89          144         233         377         610

v     987        1597       2584       4181       6765

 

v      实际上,斐波那契数列中的各项存在如下递推关系:

v      n=n-1+Fn-2 (n3)

v      这种后项由前面的项按一定的数学关系来求得的方法,叫递推。解决递推问题必须具备两个条件:

v      1)初始条件;

v      2)递推关系(或递推公式)。

v      在上例中,初始条件为:f1=1,f2=1;递推公式为:f3=f2+f1,用f1,f2,f3代表三个数,在每一次循环中它们代表不同的数。在程序运行过程中,这些变量不断地以新值取代原值,这种不断以新值取代原值得操作称为迭代。程序中的f1,f2,f3称为迭代变量,它们的值在不断地变化被迭代的。对于递推问题一般可以用迭代方法来处理,但有时不用迭代方法也很简洁。如上面的例子,由于我们知道了它的递推关系,就可以这样来设计程序:

v      程序清单

v      REM L10-12B

v      DIM f(20)

v      f(1) = 1

v      f(2) = 1

v      PRINT f(1), f(2),

v      FOR i = 3 TO 20

v           f(i) = f(i - 1) + f(i - 2)

v           PRINT f(i),

v      NEXT i

v      PRINT

v      END

 

v      学习任务10有一堆游戏棒,第一个参加游戏的人取走了一半多一根,第二个游戏者再将剩下的取走一半多一根,以此类推,以后的游戏者均取走前一次剩下的一半多一根,到第10个人来取时,发现只剩下一根了。问:游戏开始前这堆游戏棒共有多少根?

v      问题分析

v          平时,我们比较习惯用顺推的方法来解决问题,但对本题类型的问题,不妨用反向思维来考虑。根据题意:

v          10个人来取时         1根,

v          推定第9个人来取时      4根,  (1+1)*2

v          推定第8个人来取时      10根, (4+1)*2

v          推定第7个人来取时      22根, (10+1)*2

v          推定第6个人来取时      46根, (22+1)*2

v          推定第5个人来取时      94根, (46+1)*2

v          推定第4个人来取时      190根,即(97+1)*2

v          推定第3个人来取时      382根,即(190+1)*2

v          推定第2个人来取时      766根,即(382+1)*2

v          推定第1个人来取时      1534根,即(766+1)*2

v          根据以上的推导过程,可以设计出这样的算法:

v          0)将1赋给S作为初值,S是迭代变量;

v          1)通过循环完成逆推的过程,迭代公式(S+1)*2,其中S是在不断变化的;

v          2)输出9遍循环后的S值。

 

【程序清单

REM L10_13A

S = 1

FOR I = 9 TO 1 STEP -1

    S = (S + 1) * 2

NEXT I

PRINT S=";S

END

【运行结果

S=1534

   

 

v    我们是否也可以采用顺推的方法来解决?我们还是先来分析一下:

v        S为总游戏捧数,A为每次取走后的所剩游戏棒数。让S0开始进行搜索,每次逐步递增1,直到找出经过9次取游戏棒后剩下的游戏捧数为1时结束。

v        每次取走游戏棒数为A2+1

v        每次取走后的剩下的游戏棒数为A-(A2+1),于是得出递推公式为:

v        A=A-A2-1

v        9次后剩下的游戏棒数A=1就终止。这时的S应该是最初的总游戏棒数。

v        因此在上述的内循环外,还要有一个外循环来给S计数,当S计数的值满足按条件取9次后剩下A=l为止。 S的初值可以取0,终值到底取多少为好是个未知数,所以不能用计数循环,只能用条件循环,直到满足A=1终止。

v    特别要注意的:在这个条件循环中用S=S+1来为S计数,决不能再用S作为迭代变量。应该用 A来作迭代变量,每次在操作内循环之前,把S赋给A。由此可见,同一问题的顺推与逆推除了递推公式不同外,迭代变量也有所改变。

 

 

v   程序清单

v   REM L10_13B

v   S = 0

v   DO

v     S = S + 1: A = S

v     FOR I = 1 TO 9

v       A = A - A / 2 - 1

v     NEXT I

v   LOOP UNTIL A = 1

v   PRINT S=";S

v   END

v     上面分别介绍了两种递推方法:顺推和逆推。无论是哪一种递推方法,最关键的是要找到递推公式。只要找到了递推公式,程序就很容易实现。

 

v    【学习任务11数列问题:有一数列 A(N)的前几项为01261644120328,已知后一项和前两项有某种关系,试编程求出前N项的和,并将这N个数及其和打印输出。

v    【问题分析

v    问题的关键是找出数列A(N)的规律,然后将A(1)A(2)…A(N)相加即可。

v        由题意知:A(N)A(N—1)A(N—2)之间存在关系

v        A(1)=0

v        A(2)=1

v        A(3)=2*(A(2)+A(1))=2*(1+0)=2

v        A(4)=2*(A(3)+A(2))=2*(2+1)=6

v        A(5)=2*(A(4)+A(3))=2*(6+2)=16

v        

v    根据分析,很显然有A(N)=2*(A(N-1)+A(N-2))(N3)

 

v     程序清单

v     REM L10-14

v     INPUT "输入要求数列的项数N=";N

v     DIM A(N)

v     A(1) = 0: A(2) = 1

v     S = A(1) + A(2)

v     FOR I = 3 TO N

v        A(I) = 2 * A(I - 1) + 2 * A(I - 2)

v        S = S + A(I)

v     NEXT I

v     PRINT "输出前";N;"项,各项的值:"

v     FOR I = 1 TO N

v        PRINT A(I),

v     NEXT I

v     PRINT

v     PRINT "前";N;"项之和是I:";S

v     END

v     运行结果

v         输入要求数列的项数N=? 10

v         输出前10项,各项的值:

v         0       1        2        6        16

v         44     120    328    896    2448       10项之和是3861

0

阅读 收藏 喜欢 打印举报/Report
  

新浪BLOG意见反馈留言板 欢迎批评指正

新浪简介 | About Sina | 广告服务 | 联系我们 | 招聘信息 | 网站律师 | SINA English | 产品答疑

新浪公司 版权所有