递归与递推上机习题

递归与递推上机习题
递归与递推上机习题

进制转换

源程序名change.??? (pas,c,cpp)

可执行文件名 change.exe

输入文件名 change.in

输出文件名 change.out

请你编一程序实现两种不同进制之间的数据转换。

输入:

输入数据共有三行,第一行是一个正整数,表示需要转换的数的进制n(2≤n≤16),第二行是一个n进制数,若n>10则用大写字母A~F表示数码10~15,并且该n进制数对应的十进制的值不超过1000000000,第三行也是一个正整数,表示转换之后的数的进制m(2≤m≤16)。

输出:

输出仅一行,包含一个正整数,表示转换之后的m进制数。

样例:

change.in

16

FF

2

change.out

11111111

数的计算(20分) count.pas

问题描述

我们要求找出具有下列性质数的个数(包含输入的自然数n):

先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理:

1.不作任何处理;

2.在它的左边加上一个自然数,但该自然数不能超过原数的一半;

3.加上数后,继续按此规则进行处理,直到不能再加自然数为止.

样例: 输入: 6

满足条件的数为 6 (此部分不必输出)

16

26

126

36

136

输出: 6

黑白棋子的移动

源程序名 chessman.???(pas/c/cpp)

可执行文件名 chessman.exe

输入文件名 chessman.in

输出文件名 chessman.out

有2n个棋子(n≥4)排成一行,开始为位置白子全部在左边,黑子全部在右边,如下图为n=5的情况:

○○○○○●●●●●

移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能移成黑白相间的一行棋子。如n=5时,成为:

○●○●○●○●○●

任务:编程打印出移动过程。

样例

chessman.in chessman.out

7 step 0:ooooooo*******--

step 1:oooooo--******o*

step 2:oooooo--******o*

step 3:ooooo--*****o*o*

step 4:ooooo*****--o*o*

step 5:oooo--****o*o*o*

step 6:oooo****--o*o*o*

step 7:ooo--***o*o*o*o*

step 8:ooo*o**--*o*o*o*

step 9:o--*o**oo*o*o*o*

step 10:o*o*o*--o*o*o*o*

step 11:--o*o*o*o*o*o*o*

问题分析

我们先从n=4开始试试看,初始时:

○○○○●●●●

第1步:○○○——●●●○●(—表示空位)

第2步:○○○●○●●——●

第3步:○——●○●●○○●

第4步:○●○●○●——○●

第5步:——○●○●○●○●

如果n=5呢?我们继续尝试,希望看出一些规律,初始时:

○○○○○●●●●●

第1步:○○○○——●●●●○●

第2步:○○○○●●●●——○●

这样,n=5的问题又分解成了n=4的情况,下面只要再做一下n=4的5个步骤就行了。同理,n=6的情况又可以分解成n=5的情况,……,所以,对于一个规模为n的问题,我们很容易地就把它分治成了规模为n-1的相同类型子问题。

数据结构如下:数组c[1..max]用来作为棋子移动的场所,初始时,c[1]~c[n]存放白子(用字符o表示),c[n+1]~c[2n]存放黑子(用字符*表示),c[2n+1],c[2n+2]为空位置(用字符—表示)。最后结果在c[3]~c[2n+2]中。

Hanoi双塔问题

源程序名 hanoi.???(pas/c/cpp)

可执行文件名 hanoi.exe

输入文件名 hanoi.in

输出文件名 hanoi.out

给定A,B,C三根足够长的细柱,在A柱上放有2n个中间有空的圆盘,共有n个不同的尺寸,每个尺寸都有两个相同的圆盘,注意这两个圆盘是不加区分的(下图为n=3的情形)。现要将这些国盘移到C柱上,在移动过程中可放在B柱上暂存。要求:

(1)每次只能移动一个圆盘;

(2) A、B、C三根细柱上的圆盘都要保持上小下大的顺序;

任务:设An为2n个圆盘完成上述任务所需的最少移动次数,对于输入的n,输出An。【输入】

输入文件hanoi.in为一个正整数n,表示在A柱上放有2n个圆盘。

【输出】

输出文件hanoi.out仅一行,包含一个正整数,为完成上述任务所需的最少移动次数An。

【输入输出样例2】

【限制】

对于50%的数据, 1<=n<=25

对于100% 数据, 1<=n<=200

【提示】

设法建立An与An-1的递推关系式。

算24点

源程序名point24.??? (pas,c,cpp)

可执行文件名 point24.exe

输入文件名point24.in

输出文件名 point24.out

几十年前全世界就流行一种数字游戏,至今仍有人乐此不疲.在中国我们把这种游戏称为“算24点”。您作为游戏者将得到4个1~9之间的自然数作为操作数,而您的任务是对这4个操作数进行适当的算术运算,要求运算结果等于24。

您可以使用的运算只有:+,-,*,/,您还可以使用()来改变运算顺序。注意:所有的中间结果须是整数,所以一些除法运算是不允许的(例如,(2*2)/4是合法的,2*(2/4)是不合法的)。下面我们给出一个游戏的具体例子:

若给出的4个操作数是:1、2、3、7,则一种可能的解答是1+2+3*7=24。

输入

只有一行,四个1到9之间的自然数。

输出

如果有解的话,只要输出一个解,输出的是三行数据,分别表示运算的步骤。其中第一行是输入的两个数和一个运算符和运算后的结果,第二行是第一行的结果和一个输入的数据、运算符、运算后的结果;第三行是第二行的结果和输入的一个数、运算符和“=24”。如果两个操作数有大小的话则先输出大的。

如果没有解则输出“No answer!”

样例

point24.in

1 2 3 7

point24.out

2+1=3

7*3=21

21+3=24

6(p4) p4.pas p4.in p4.out

[问题描述]:

如图,A 点有一个过河卒,需要走到目标 B 点。卒行走规则:可以向下、或者向右。同时在棋盘上的任一点有一个对方的马(如上图的C点),该马所在的点和所有跳跃一步可达的点称为对方马的控制点。例如上图 C 点上的马可以控制 9 个点(图中的P1,P2 … P8 和 C)。卒不能通过对方马的控制点。

棋盘用坐标表示,A 点(0,0)、B 点(n,m)(n,m 为不超过 20 的整数,并由键盘输入),同样马的位置坐标是需要给出的(约定: C<>A,同时C<>B)。现在要求你计算出卒从A 点能够到达 B 点的路径的条数。

[输入]:

键盘输入

B点的坐标(n,m)以及对方马的坐标(X,Y){不用盘错}

[输出]:

屏幕输出

一个整数(路径的条数)。

[输入输出样例]:

输入:

6 6 3 2

输出:

17

《递归算法与递归程序》教学设计

递归算法与递归程序 岳西中学:崔世义一、教学目标 1知识与技能 (1) ?认识递归现象。 (2) ?使用递归算法解决冋题往往能使算法的描述乘法而易于表达 (3) ?理解递归三要素:每次递归调用都要缩小规模;前次递归调用为后次作准备:递归调用必须有条件进行。 (4) ?认识递归算法往往不是咼效的算法。 (5) ? 了解递归现象的规律。 (6) ?能够设计递归程序解决适用于递归解决的问题。 (7) ?能够根据算法写出递归程序。 (8) ? 了解生活中的递归现象,领悟递归现象的既有重复,又有变化的特点,并且从中学习解决问题的一种方法。 2、方法与过程 本节让同学们玩汉诺塔的游戏,导入递归问题,从用普通程序解决斐波那契的兔子问题入手,引导学生用自定义了一个以递归方式解决的函数过程解决问题,同时让同学们做三个递归练习,巩固提高。然后让学生做练习(2) 和练习(3)这两道题目的形式相差很远,但方法和答案却是完全相同的练习,体会其中的奥妙,加深对递归算法的了解。最后用子过程解决汉诺塔的经典问题。 3、情感态度和价值观 结合高中生想象具有较强的随意性、更富于现实性的身心发展特点,综合反映出递归算法的特点,以及递归算法解答某些实践问题通常得很简洁,从而激发学生对程序设计的追求和向往。 二、重点难点 1、教学重点 (1) 了解递归现象和递归算法的特点。 (2) 能够根据问题设计出恰当的递归程序。 2、教学难点 (1) 递归过程思路的建立。 (2) 判断冋题是否适于递归解法。 (3) 正确写出递归程序。 三、教学环境 1、教材处理 教材选自《浙江省普通高中信息技术选修:算法与程序设计》第五章,原教材的编排是以本节以斐波那契的兔子问题引人,导出递归算法,从而自 定义了一个以递归方式解决的函数过程。然后利用子过程解决汉诺塔的经典问题。 教材经处理后,让同学们玩汉诺塔的游戏,导入递归问题,从用普通程序解决斐波那契的兔子问题入手,引导学生用自定义了一个以递归方式解决的函数过程解决问题,同时让同学们做三个递归练习,巩固提高。然后让学生做练习⑵ 和练习

递归方程求解方法综述

递归方程求解方法综述 摘要:随着计算机科学的逐步发展,各种各样的算法相继出现,我们需要对算法进行分析,以选择性能更好的解决方案。算法分析中计算复杂度常用递归方程来表达,因此递归方程的求解有助于分析算法设计的好坏。阐述了常用的3种求解递归方程的方法:递推法、特征方程法和生成函数法。这3种方法基本上可以解决一般规模递归方程的求解问题。 关键词:递归;递推法;特征方程;生成函数 0引言 寻求好的解决方案是算法分析的主要目的,问题的解决方案可能不只一个,好的方案应该执行时间最短,同时占有存储空间最小,故算法分析一般考虑时间复杂性、空间复杂性两方面的参数。在算法分析时我们采用时间耗费函数来表示时间参数,用当问题规模充分大时的时间耗费函数的极限表示时间复杂度。 一般算法对应的时间耗费函数常用递归方程表示,找出递归方程的解,就可以表示其对应算法复杂度的渐进阶,从而比较算法的优劣。因此研究递归方程的解法意义重大。下文将分析并给出常用递归方程的3种解法。 1递归方程的解法 递归方程是对实际问题求解的一种数学抽象,递归的本质在于将原始问题逐步划分成具有相同解题规律的子问题来解决,原始问题与子问题仅在规模上有大小区别,并且子问题的规模比原始问题的

规模要小。对于规模为n的原始问题,我们通常会寻找规模n的问题与规模n-1或者规模n/2的问题之间存在的联系,从而进一步推导出具有递归特性的运算模型。 根据递归方程的一般形式,常用的解法有三种,分别是递推法、公式法及生成函数法。下面就分别来分析其求解过程。 1.1递推法 当递归方程形式简单且阶数较低时,一般可以采用递推法求解,根据一步一步递推找到方程的递推规律,得到方程的解。下面举例说明: t(1)=0 t(n)=2t(n/2)+n2(n≥2) t(n)=2t(n/2)+n2=2(2t(n/22)+(n/2)2)+n2 =22t(n/2)2+2n2/22+n2 =22(2t(n/23)+(n/22)2)+2n2/22+n2 =23(2t(n/23)+22n2/(22)2)+2n2/(22)1+n2… =2kt(n/2k)+∑k-1i=02in2(22)i递推到这里我们就可以发现递 归规律,找到递归出口, t(1)=0,令n=2k 则可以得到如下结果:t(n) =2kt(1) +∑k-1i=0n2(1/2)i)= n2(1-(1/2)k1-1/2)=2n2-2n 上面得到方程的解,我们来分析其对应算法复杂性的渐进阶,根据渐进阶定理有:设有函数f(n),g(n)均是规模n的函数,则o(f(n))+o(g(n))=o(max(f(n), g(n)))。故有t(n)=o(n2)。 1.2公式法

关于递归与递推的那七道题

关于递归与递推的那七道题 递归与递推是动态规划最底层的东西,掌握好它对于彻底的理解动规是至关重要的,这次做的题不难,但是它很能锻练人的思维,每一道题都有多种解法。只要静下心来想,一般人都能做出来,而在做题的过程中,你会有很大的收获。 1、一只小蜜蜂... 题目是这样的,有一只经过训练的蜜蜂只能爬向右侧相邻的蜂房,不能反向爬行。请编程计算蜜蜂从蜂房a爬到蜂房b的可能路线数。 对于这种题目,我们首先得找出蜂房之间的关系,如从1只能走到2和3,从2只能走到3和4,从3只能走到4和5……,因此 我们可以得到它们的递推关系: f[a] = f[a+1]+f[a+2]; 下面我们再来找出口,把这个问题化简,即当a与b相邻时(a+1=b 或a+2=b),f[a] = 1,所以这个问题可以解决了。它就是一个递归,遇到b就结束。为了减少重复访问,我们可以用记忆化搜索来提高效率。 这个题也可以顺着来推,即从a到a有0条路线,从a到a+1有1条路线,从a 到a+2有1条路线,而a+3的路线条数来源于a+1 和a+2的路径条数。 f[a] = 0; f[a+1] = 1; f[a+2] = 1; f[a+3] = f[a+1]+f[a+2]; …… f[b] = f[b-1]+f[b-2]; 由上面的式子就可以看出,它就是一个菲波拉契数列。 2、LELE的RPG难题

题目描述:有排成一行的n个方格,用红(Red)、粉(Pink)、绿(Green)三色涂每个格子,每格涂一色,要求任何相邻的方格不能同色,且首尾两格也不同色.求全部的满足要求的涂法. 以上就是著名的RPG难题. 解法一: 这个题目经过同学们的讨论,得出了三种解法。我所用的方法还是搜索,我们先不考虑它的限制条件,把第一个格子看成是树的根,那么总共可以建成三棵树,每一棵树的结点都有三个孩子。我们的目标就是要统计这三棵树中分别从根结点走到叶子结点的总的路径条数。然后把限制条件加上,把不符合要求的路径去掉,即可得出最终的结果。具体的做法同样是记忆化搜索. 解法二:递推公式 f[n] = 3 * 2^(n-1) – f[n-1]; 解法三:数学公式 f[n] = (k-1)^n+(k-1)*(-1)^n; 证明略。 3、骨牌铺方格 题目描述:在2×n的一个长方形方格中,用一个1× 2的骨牌铺满方格,输入n ,输出铺放方案的总数. 法一: 这道题目,我是用数学方法解的,可以说是枚举。骨牌放入方格中只有两种方式,横放或竖放,设横放的有x张,竖放的有y张。则X+y = n;并且x只能是偶数(要把方格填满,横着放的骨牌只能是成对出现),而题目给出n最大为50,所x,y 完全可以很快的枚举 出来。剩下的工作只需对由x/2,y组成的多重集合进行排列就行了。这个集合中共有两类不同类型的元素,第一类元素的重数k1=x/2, 第二类元素的重数k2=y;故最后的结果为(k1+k2)!/(k1! * k2!)。 法二: 假设f[n]为铺放方案的总数,我们只考虑最后放的那几张骨牌,有两种可能,一种是只放一张,竖着放,此时的方案总数为f[n-1],还有 一种可能是放两张,横着放,此时的方案总数为f[n-2]。因此我可以得出递推公式 f[n] = f[n-1]+f[n-2]。 法三:

递推与递归练习题

练习 1.(用递归做)5个人坐在一起,问第五个人多少岁?他说比第4个人大2岁。 问第4个人岁数,他说比第3个人大2岁。问第三个人,又说比第2人大两岁。问第2个人,说比第一个人大两岁。最后问第一个人,他说是10岁。请问第五个人多大? 程序分析:利用递归的方法,递归分为回推和递推两个阶段。要想知道第五个人岁数,需知道第四人的岁数,依次类推,推到第一人(10岁),再往回推。 2.(用递归做)商人渡河问题是这样的:有三个商人,三个强盗,和一条船(船 每次只可以载小于等于两个人)他们同在河的一边,想渡过河去,但是必须保证在河的任何一边必须保证商人的数目大于等于强盗的数目,应该怎么过这条河呢? 注意:开始时商人,强盗所在的河的这边设为0状态,另一边设为1状态(也就是船开始时的一边设为0,当船驶到对岸是设为1状态,在这两个状态时,都必须符合条件) 3.(用递推做)猴子第一天摘下若干个桃子,当即吃了一半,还不过瘾, 又多吃了一个,第二天早上又将剩下的桃子吃掉一半,又多吃了一个。 以后每天早上都吃了前一天剩下的一半多一个。到第30天早上想再吃时,见只剩下1个桃子了。求第一天共摘了多少。 4.(用递推做)已知一对兔子每一个月能生一对小兔子,而一对小兔子出 生后第二个月就开始生小兔子,假如一年内没有发生死亡,则以对兔子一年能繁殖成多少对?

答案: 1.#include int age(int n) { if(n==1) return(10); else return age(n-1)+2; } void main() { int n; n=5; printf("The fifth age is %d.\n",age(n)); } 2.#include #include #include struct node /*建立一个类似栈的数据结构并且可以浏览每一个数据点*/ { int x; int y; int state; struct node *next; }; typedef struct node state; typedef state *link; link PPointer1=NULL; link PPointer2=NULL; int a1,b1; int a2,b2; /*栈中每个数据都分为0,1状态*/ void Push(int a,int b,int n) { link newnode; newnode=(link)malloc(sizeof(state)); newnode-> x=a; newnode-> y=b; newnode-> state=n; newnode-> next=NULL; if(PPointer1==NULL) { PPointer1=newnode; PPointer2=newnode; }

递推和递归作业

题1:编码(encode.???) 【问题描述】 编码工作常被运用于密文或压缩传输。这里我们用一种最简单的编码方式进行编码:把一些有规律的单词编成数字。 字母表中共有26个字母{a,b,……,z},这些特殊的单词长度不超过6且字母按升序排列。把所有这样的单词放在一起,按字典顺序排列,一个单词的编码就对应着它在字典中的位置。 例如: a --> 1 b --> 2 z --> 26 ab --> 27 ac --> 28 你的任务就是对于所给的单词,求出它的编码。 【输入格式】 仅一行,被编码的单词。 【输出格式】 仅一行,对应的编码。如果单词不在字母表中,输出0。 【输入样例】 ab 【输出样例】 27 题2:特殊的子集(subset.???) 【问题描述】 集合M={1,2,3,……n}的子集中,有一些是不含相邻自然数元素的。例如:n=4时,集合{1,3}是满足要求的,而{1,3,4}是不满足的,因为它含有相邻自然数3和4。把所有满足要求的子集记作S i,对于每一个S i计算出它的所有元素的乘积T i,求∑T i2。 【输入格式】 仅一行,包括一个正整数n(n≤100) 【输出格式】 仅一行,即T i的平方和,可能会超出长整型范围。 【输入样例】 4

【输出格式】 119 题3:素数环(prime.???) 【问题描述】 给定一个n,求1..n组成的环,使得环上相邻的元素和为素数。 【输入格式】 n(1<=n<=10) 【输出格式】 把1放在第一位置,按照字典顺序不重复的输出所有解(顺时针,逆时针算不同的两种),相邻两数之间严格用一个整数隔开,每一行的末尾不能有多余的空格。 【输入样例】 8 【输出样例】 1 2 3 8 5 6 7 4 1 2 5 8 3 4 7 6 1 4 7 6 5 8 3 2 1 6 7 4 3 8 5 2 题4:火力网(fire.???) 【问题描述】 在一个n*n的阵地中,有若干炮火不可摧毁的石墙,现在要在这个阵地中的空地上布置一些碉堡。假设碉堡只能向上下左右四个方向开火,由于建筑碉堡的材料挡不住炮火,所以任意一个碉堡都不能落在其它碉堡的火力范围内,请问至多可建造几座碉堡? 【输入格式】 第一行一个整数n(n<=10)。 下面n行每行为一个由n个字符构成的字符串,表示阵地的布局,包括空地('.'),和石墙('X')。 【输出格式】 一个整数,即最多可建造的碉堡数。 【输入样例】 4

使用分治策略递归和非递归和递推算法解决循环赛日程表课程设计报告

《算法设计与分析》 课程设计报告 题目:循环赛日程表 院(系):信息科学与工程学院 专业班级:软工 学生姓名: 学号: 指导教师: 2018 年 1 月 8 日至 2018 年 1 月 19 日

算法设计与分析课程设计任务书

目录 1 常用算法 (1) 1.1分治算法 (1) 基本概念: (1) 1.2递推算法 (2) 2 问题分析及算法设计 (5) 2.1分治策略递归算法的设计 (5) 2.2 分治策略非递归算法的设计 (7) 2.3 递推策略算法的设计 (8) 3 算法实现 (9) 3.1分治策略递归算法的实现 (9) 3.2 分治策略非递归算法的实现 (10) 3.3 递推策略算法的实现 (12) 4 测试和分析 (15) 4.1分治策略递归算法测试 (15) 4.2分治策略递归算法时间复杂度的分析 (16) 4.3 分治策略非递归算法测试 (16) 4.4分治策略非递归算法时间复杂度的分析 (17) 时间复杂度为:O(5^(n-1)) (17) 4.5 递推策略算法测试 (17) 4.6 递推策略算法时间复杂度的分析 (18) 时间复杂度为:O(5^(n-1)) (18) 4.7 三种算法的比较 (18) 5 总结 (19) 参考文献 (20)

1 常用算法 1.1分治算法 基本概念: 在计算机科学中,分治法是一种很重要的算法。字面上的解释是“分而治之”,就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并。这个技巧是很多高效算法的基础,如排序算法(快速排序,归并排序),傅立叶变换(快速傅立叶变换)…… 任何一个可以用计算机求解的问题所需的计算时间都与其规模有关。问题的规模越小,越容易直接求解,解题所需的计算时间也越少。例如,对于n个元素的排序问题,当n=1时,不需任何计算。n=2时,只要作一次比较即可排好序。n=3时只要作3次比较即可,…。而当n较大时,问题就不那么容易处理了。要想直接解决一个规模较大的问题,有时是相当困难的。 基本思想及策略: 分治法的设计思想是:将一个难以直接解决的大问题,分割成一些规模较小的相同问题,以便各个击破,分而治之。 分治策略是:对于一个规模为n的问题,若该问题可以容易地解决(比如说规模n较小)则直接解决,否则将其分解为k个规模较小的子问题,这些子问题互相独立且与原问题形式相同,递归地解这些子问题,然后将各子问题的解合并得到原问题的解。这种算法设计策略叫做分治法。 如果原问题可分割成k个子问题,1

Problem_递推递归与贪心_

长郡中学NOIP递推递归贪心试题 试题名称程序名输入文件输出文件时限空间铺砖问题puzhuan. cpp puzhuan.in puzhuan.out 1s 128M 三角形计数TricountUVa. cpp TricountUVa.in TricountUVa.out 1s 128M 新汉诺塔Hanoi.cpp Hanoi.in Hanoi.out 1s 128M 生产调度 prod .cpp prod.in prod.out 1s 128M 最大乘积 maxmul.cpp maxmul.in maxmul.out 1s 128M 铺砖 【问题描述】 用1 x 1和2 x 2的磁砖不重叠地铺满N x 3的地板,共有多少种方案? 【输入】 仅一行包含一个正整数 N ( 1 <= N <= 1000 )。 【输出】 一行包含一个整数表示方案数,由于结果可能很大,你只需要输出这个答案mod 12345的值。 【样例】 puzhuan.in 2 puzhuan.out 3

三角形计数 【问题描述】 有多少种方法可以从1,2,3...,n中选3个不同的整数。使得以它们为三边长可以组成三角形? 比如n=5时有3种方法(2,3,4),(2,4,5),(3,4,5).n=8时有22种方法。 【输入】 输入包含多组测试数据,每组测试数据为一行整数n(3≤n≤1 000 000)。输入用n<3的标志结束。 【输出】 对于每组数据,输出其方案数(每组占一行) 【样例】 TricountUVa. IN 5 8 1 TricountUVa. OUT 3 22 数据组数不会超过20组。 对于25%的数据:(3≤n≤100) 对于50%的数据:(3≤n≤1 000) 对于100%的数据:(3≤n≤1 000 000)

递推-递归-分治-回溯

递推算法 在程序编辑过程中,我们可能会遇到这样一类问题,出题者告诉你数列的前几个数,或通过计算机获取了数列的前几个数,要求编程者求出第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)等。 我们再来分析一下尼科梅彻斯定理。定理内容是:任何一个整数的立方都可以写成一串连续的奇数和,如:43=13+15+17+19=64。 从键盘输入一个整数n,要求写出其相应的连续奇数。 我们不妨从简单入手,枚举几个较小的数据: 13=1 23=3+5 33=7+9+11 43=13+15+17+19 53=21+23+25+27+29 根据上面的例子,读者不难看出: (1)输入为n时,输出应有n项。 (2)输入分别为1,2,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,其余同算法二。下面我们来分析两个与动物有关的趣题。

第3章-程序与递归:组合、抽象与构造

第3章程序与递归:组合、抽象与构造 1、关于计算系统与程序,下列说法正确的是_____。 (A)只有用计算机语言编写出来的代码才是程序,其他都不能称其为程序; (B)构造计算系统是不需要程序的,程序对构造计算系统没有什么帮助; (C)任何系统都需要程序,只是这个程序是由人来执行还是由机器自动执行,可以由机器自动执行程序的系统被称为计算系统; (D)程序是用户表达的随使用者目的不同而千变万化的复杂动作,不是使用者实现的而是需要计算系统事先完成的。 2、关于程序,下列说法不正确的是_____。 (A)“程序”是由人编写的、以告知计算系统实现人所期望的复杂动作; (B)“程序”可以由系统自动解释执行,也可以由人解释由系统执行; (C)普通人是很难理解“程序”的,其也和“程序”无关; (D)“程序”几乎和每个人都有关系,如自动售票系统、自动取款机等。 3、关于程序,下列说法不正确的是_____。 (A)程序的基本特征是复合、抽象与构造; (B)复合就是对简单元素的各种组合,即将一个(些)元素代入到另一个(些)元素中; (C)抽象是对各种元素的组合进行命名,并将该名字用于更复杂的组合构造中; (D)程序就是通过组合、抽象、再组合等构造出来的; (E)上述说法有不正确的。 4、一般而言,设计和实现一个计算系统,需要设计和实现_____。 (A)基本动作和程序; (B)基本动作和控制基本动作的指令; (C)基本动作、控制基本动作的指令和一个程序执行机构; (D)基本动作、控制基本动作的指令和程序。

5、一般而言,一个较高抽象层次的计算系统是可以这样实现的,即_____。 (A)将较低抽象层次的重复性组合,命名为较高抽象层次的指令; (B)利用较高抽象层次的指令进行复合、抽象与构造,即形成高抽象层次的程序; (C)高抽象层次的程序通过其程序执行机构解释为高抽象层次的指令及其操作次序; (D)高抽象层次的指令被替换为低抽象层次的程序,再由低抽象层次的程序执行机构解释并执行。 (E)上述A-D全部。 答案是:E 6、熟悉下列运算组合式(前缀表达式),其中结果为56的是_____。 (A) (* 7 (+ 5 2)); (B) (* (+ 5 3) (+ 5 2)); (C) (+ 20 (+ 6 6)); (D) (- (* 9 8) (- 20 2))。 //本题考查基本运算组合式的构造与计算,尤其是嵌套的运算组合式的计算 答案是:B 7、对于计算式,其正确的运算组合式(前缀表示法)为_____。 (A) (/ (+ 10 / 20 + 8 4) (+ * 3 6 * 8 2 )); (B) ((10 + (20 / (8 + 4))) / ((3 * 6) + (8 * 2))); (C) (/ (+ 10 (/ 20 (+ 8 4))) (+ (* 3 6) (* 8 2))); (D) (/ (/ 20 (+ 10 (+ 8 4))) (* (+ 3 6) (+ 8 2)))。 //本题考查运算组合式的书写与构造 答案是:C 8、请用define运算,定义一个过程实现计算a3,其正确定义的过程为_____。 (A) (define cube a (* a a a)); (B) (define (cube x) (* x x x)); (C) (define (cube a (* a a a))); (D) (define (cube a) (* x x x)))。

递归与递推

2.1 遍历问题 【问题描述】 我们都很熟悉二叉树的前序、中序、后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中序遍历序列你也能求出它的前序遍历。然而给定一棵二叉树的前序和后序遍历,你却不能确定其中序遍历序列,考虑如下图中的几棵二叉树: 所有这些二叉树都有着相同的前序遍历和后序遍历,但中序遍历却不相同。 【输入】 输入数据共两行,第一行表示该二叉树的前序遍历结果s1,第二行表示该二叉树的后序遍历结果s2。 【输出】 输出可能的中序遍历序列的总数,结果不超过长整型数。 【样例】 travel.in abc cba travel.out 4 2.2 产生数 【问题描述】 给出一个整数n(n<1030)和m个变换规则(m≤20)。 约定:一个数字可以变换成另一个数字,规则的右部不能为零,即零不能由另一个数字变换而成。而这里所说的一个数字就是指一个一位数。 现在给出一个整数n和m个规则,要你求出对n的每一位数字经过任意次的变换(0次或多次),能产生出多少个不同的整数。 【输入】 共m+2行,第一行是一个不超过30位的整数n,第2行是一个正整数m,接下来的m 行是m个变换规则,每一规则是两个数字x、y,中间用一个空格间隔,表示X可以变换成Y。 【输出】 仅一行,表示可以产生的不同整数的个数。 【样例】 build.in 1 2 3

2 1 2 2 3 build.out 6 2.3 出栈序列统计 【问题描述】 栈是常用的一种数据结构,有n个元素在栈顶端一侧等待进栈,栈顶端另一侧是出栈序列。你已经知道栈的操作有两种:push和pop,前者是将一个元素进栈,后者是将栈顶元素弹出。现在要使用这两种操作,由一个操作序列可以得到一系列的输出序列。请你编程求出对于给定的n,计算并输出由操作数序列1,2,…,n,经过一系列操作可能得到的输出序列总数。 【输入】 就一个数n(1≤n≤1000)。 【输出】 一个数,即可能输出序列的总数目。 【样例】 stack.in 3 stack.out 5 2.4 计数器 【问题描述】 一本书的页数为N,页码从1开始编起,请你求出全部页码中,用了多少个0,1,2,…,9。其中一个页码不含多余的0,如N=1234时第5页不是0005,只是5。 【输入】 一个正整数N(N≤109),表示总的页码。 【输出】 共十行:第k行为数字k-1的个数。 【样例】 count.in 11 count.Out 1 4 1 1 1 1 1 1

递推与递归算法练习题2013.10

递推与递归算法练习题 1.实数数列(realsn) 源程序名realsn.??? (pas,c,cpp) 输入文件名realsn.in 输出文件名realsn.out 时间限制1秒 【问题描述】 一个实数数列共有n项,已知a[i]=(a[i-1]-a[i+1])/2+d,(1

用递推关系理论分析递归算法的时间复杂度

用递推关系理论分析递归算法的时间复杂度 [ 摘要 ] 对算法进行时间复杂度分析是算法分析与研究的重要内容,而对递归算法分析其时间复杂度时往往比较困难。 本文提出了用组合数学中的递推关系理论来分析一些特殊的递归算法的时间复杂度, 并同时得出三个推论, 在算法的分析与研究方面具有一定的参考价值。 [ 关键词 ] 时间复杂度,递归,母函数 1. 引言 一个程序在计算机上运行时所耗费的时间取决于对源程序进行编译所需时间、 计算机执行每条指令所需时间、 程序中指令重复执行的次数。 前两条依赖于实现算法的计算机软件、硬件系统,亦即依赖于实现算法所用语言的编译程序的性能和计算机本身的速度。因此习惯上常常用重复执行次数最多的语句频度来分析算法的时间复杂度, 记为t (n ),其中n 为问题的规模或大小。例如对n 个存放于数组a[n] 中的数进行选择法排序的算法: for( i=0; i %c", one, three); }else{ hanoi(n-1, one, three, two); printf("%c —> %c", one, three);

递归方程求解方法综述

龙源期刊网 https://www.360docs.net/doc/ea13979923.html, 递归方程求解方法综述 作者:郭萌萌 来源:《软件导刊》2011年第12期 摘要:随着计算机科学的逐步发展,各种各样的算法相继出现,我们需要对算法进行分析,以选择性能更好的解决方案。算法分析中计算复杂度常用递归方程来表达,因此递归方程的求解有助于分析算法设计的好坏。阐述了常用的3种求解递归方程的方法:递推法、特征方程法和生成函数法。这3种方法基本上可以解决一般规模递归方程的求解问题。 关键词:递归;递推法;特征方程;生成函数 中图分类号:TP301文献标识码:A文章编号:(2011) 作者简介:郭萌萌(1983- ),女,山东济南人,硕士,山东英才学院计算机电子信息工程 学院讲师,研究方向为软件工程、算法分析与设计。 0引言 寻求好的解决方案是算法分析的主要目的,问题的解决方案可能不只一个,好的方案应该执行时间最短,同时占有存储空间最小,故算法分析一般考虑时间复杂性、空间复杂性两方面的参数。在算法分析时我们采用时间耗费函数来表示时间参数,用当问题规模充分大时的时间耗费函数的极限表示时间复杂度。 一般算法对应的时间耗费函数常用递归方程表示,找出递归方程的解,就可以表示其对应算法复杂度的渐进阶,从而比较算法的优劣。因此研究递归方程的解法意义重大。下文将分析并给出常用递归方程的3种解法。 1递归方程的解法 递归方程是对实际问题求解的一种数学抽象,递归的本质在于将原始问题逐步划分成具有 相同解题规律的子问题来解决,原始问题与子问题仅在规模上有大小区别,并且子问题的规模比原始问题的规模要小。对于规模为n的原始问题,我们通常会寻找规模n的问题与规模n-1或者规模n/2的问题之间存在的联系,从而进一步推导出具有递归特性的运算模型。 根据递归方程的一般形式,常用的解法有三种,分别是递推法、公式法及生成函数法。下面就分别来分析其求解过程。

迭代与递推

迭代与递推 1)迭代法也称“辗转法”,是一种不断用变量的旧值递推出新值的解决问题的方法。迭代算法一般用于数值计算。迭代法应该是我们早已熟悉的算法策略,程序设计语言课程中所学的累加、累乘都是迭代算法策略的基础应用。例如:斐波那契数列 例子:兔子繁殖问题 一对兔子从出生后第三个月开始,每月生一对小兔子。小兔子到第三个月又开始生下一代小兔子。假若兔子只生不死,一月份抱来一对刚出生的小兔子,问一年中每个月各有多少只兔子。 ?问题分析 因为一对兔子从出生后第三个月开始每月生产一对小兔子,则每月新下生的小兔子的对儿数显然由前两个月的小兔子的对儿数决定。则繁殖过程如下: 一月二月三月四月五月六月…… 1 1 1+1= 2 2+1= 3 3+2=5 5+3=8 …… ?数学建模(斐波那契数列) y1=y2=1,yn=yn-1+yn-2,n=3,4,5,…… 2)倒推法的概念 ?倒推法:是对某些特殊问题所采用的违反通常习惯的,从后向前推解问题的方法。例如,在不知前提条件的情况下,由结果倒过来推解它的前提条件,从而求解问题。又如,由于存储的要求,而必须从后向前进行推算。另外,在对一些问题进行分析或建立数学模型时,

从前向后分析问题感到比较棘手,而采用倒推法,则问题容易理解和解决。 例子:穿越沙漠问题 用一辆吉普车穿越1000公里的沙漠。吉普车的总装油量为500加仑,耗油率为1加仑/公里。由于沙漠中没有油库,必须先用这辆车在沙漠中建立临时油库。该吉普车以最少的耗油量穿越沙漠,应在什么地方建油库,以及各处的贮油量。 ?问题分析 贮油点问题要求要以最少的耗油量穿越沙漠,即到达终点时,沙漠中的各临时油库和车的装油量均为0。这样只能从终点开始向前倒着推解贮油点和贮油量。 ?数学模型 根据耗油量最少目标的分析,下面从后向前分段讨论。 第一段长度为500公里且第一个加油点贮油为500加仑。 第二段中为了贮备油,吉普车在这段的行程必须有往返。 下面讨论怎样走效率高: 1)首先不计方向这段应走奇数次(保证最后向前走)。 2)每次向前行进时吉普车是满载。 3)要能贮存够下一加油点的贮油量,路上耗油又最少。 ?综上分析 从终点开始分别间隔 500,500/3,500/5,500/7,……(公里)设立贮油点,直到总距离超过1000公里。每个贮油点的油量为500,1000,1500,……。 ?终极解释:

递归递推POJ-1664 放苹果

Description 把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(用K表示)5,1,1和1,5,1 是同一种分法。 Input 第一行是测试数据的数目t(0 <= t <= 20)。以下每行均包含二个整数M和N,以空格分开。1<=M,N<=10。 Output 对输入的每组数据M和N,用一行输出相应的K。 Sample Input 1 7 3 Sample Output 8 /* 功能Function Description: POJ-1664 开发环境Environment: DEV C++ 4.9.9.1 技术特点Technique: 版本Version: 作者Author: 可笑痴狂 日期Date: 20120815 备注Notes: 解题分析: 设f(m,n) 为m个苹果,n个盘子的放法数目,则先对n作讨论, 当n>m:必定有n-m个盘子永远空着,去掉它们对摆放苹果方法数目不产生影响。即if(n>m) f(m,n) = f(m,m) 当n<=m:不同的放法可以分成两类: 1、有至少一个盘子空着,即相当于f(m,n) = f(m,n-1); 2、所有盘子都有苹果,相当于可以从每个盘子中拿掉一个苹果,不影响不同放法的数目,即f(m,n) = f(m-n,n). 而总的放苹果的放法数目等于两者的和,即f(m,n) =f(m,n-1)+f(m-n,n)

递归出口条件说明: 当n=1时,所有苹果都必须放在一个盘子里,所以返回1; 当没有苹果可放时,定义为1种放法; 递归的两条路,第一条n会逐渐减少,终会到达出口n==1; 第二条m会逐渐减少,因为n>m时,我们会return f(m,m)所以终会到达出口m==0. */ #include int fun(int m,int n) //m个苹果放在n个盘子中共有几种方法 { if(m==0||n==1) //因为我们总是让m>=n来求解的,所以m-n>=0,所以让m=0时候结束,如果改为m=1, return 1; //则可能出现m-n=0的情况从而不能得到正确解 if(n>m) return fun(m,m); else return fun(m,n-1)+fun(m-n,n); } int main() { int T,m,n; scanf("%d",&T); while(T--) { scanf("%d%d",&m,&n); printf("%d\n",fun(m,n)); } }

递归与递推上机习题

进制转换 源程序名change.??? (pas,c,cpp) 可执行文件名 change.exe 输入文件名 change.in 输出文件名 change.out 请你编一程序实现两种不同进制之间的数据转换。 输入: 输入数据共有三行,第一行是一个正整数,表示需要转换的数的进制n(2≤n≤16),第二行是一个n进制数,若n>10则用大写字母A~F表示数码10~15,并且该n进制数对应的十进制的值不超过1000000000,第三行也是一个正整数,表示转换之后的数的进制m(2≤m≤16)。 输出: 输出仅一行,包含一个正整数,表示转换之后的m进制数。 样例: change.in 16 FF 2 change.out 11111111 数的计算(20分) count.pas 问题描述 我们要求找出具有下列性质数的个数(包含输入的自然数n): 先输入一个自然数n(n<=1000),然后对此自然数按照如下方法进行处理: 1.不作任何处理; 2.在它的左边加上一个自然数,但该自然数不能超过原数的一半; 3.加上数后,继续按此规则进行处理,直到不能再加自然数为止. 样例: 输入: 6 满足条件的数为 6 (此部分不必输出) 16 26 126 36 136 输出: 6

黑白棋子的移动 源程序名 chessman.???(pas/c/cpp) 可执行文件名 chessman.exe 输入文件名 chessman.in 输出文件名 chessman.out 有2n个棋子(n≥4)排成一行,开始为位置白子全部在左边,黑子全部在右边,如下图为n=5的情况: ○○○○○●●●●● 移动棋子的规则是:每次必须同时移动相邻的两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。每次移动必须跳过若干个棋子(不能平移),要求最后能移成黑白相间的一行棋子。如n=5时,成为: ○●○●○●○●○● 任务:编程打印出移动过程。 样例 chessman.in chessman.out 7 step 0:ooooooo*******-- step 1:oooooo--******o* step 2:oooooo--******o* step 3:ooooo--*****o*o* step 4:ooooo*****--o*o* step 5:oooo--****o*o*o* step 6:oooo****--o*o*o* step 7:ooo--***o*o*o*o* step 8:ooo*o**--*o*o*o* step 9:o--*o**oo*o*o*o* step 10:o*o*o*--o*o*o*o* step 11:--o*o*o*o*o*o*o* 问题分析 我们先从n=4开始试试看,初始时: ○○○○●●●● 第1步:○○○——●●●○●(—表示空位) 第2步:○○○●○●●——● 第3步:○——●○●●○○● 第4步:○●○●○●——○● 第5步:——○●○●○●○● 如果n=5呢?我们继续尝试,希望看出一些规律,初始时: ○○○○○●●●●● 第1步:○○○○——●●●●○● 第2步:○○○○●●●●——○● 这样,n=5的问题又分解成了n=4的情况,下面只要再做一下n=4的5个步骤就行了。同理,n=6的情况又可以分解成n=5的情况,……,所以,对于一个规模为n的问题,我们很容易地就把它分治成了规模为n-1的相同类型子问题。

递推数列与递归算法

递推数列与递归算法 【问题】怎样用计算机程序解决裴波那契数列中的计算问题。 【目的】认识和了解计算机处理问题时的递推与递归算法的实现方法。 【预备知识】 (一)裴波那契数列 在数学史上,有一个著名的关于兔子生儿育女的问题: 假定兔子在出生两个月后就有生育能力,并且每一对有生育能力的兔子每个月生一对兔子。那么从一对有生育能力的兔子开始,整整一年之后,兔子的总数将有多少对? 有一位意大利数学家,名叫裴波那契(Fibonacci,约1170-1250),在他1228年的手稿中,详细研究了上面这个有趣的问题。 他用按月盘点的方法解答这道复杂问题。 第一个月的月底,老兔子生下1对小兔子。原来1对老的,加上1对小的,1+1=2,有2对兔子; 第二个月的月底,老兔子生下1对小兔子。1对新兔子,加上原来已有的2对,1+2=3,有了3对兔子; 第三个月的月底,老兔子再次生下1对小兔子,而第一个月出生的一对兔子现在已经发育成熟,开始生儿育女,也生下一对兔子。所以这个月出生2对新兔子,加上原来已有的3对,2+3=5,有了5对兔子; 如此继续,通过递推,可以算出,在这一年中,每个月的月底,成对兔子的数目(以“对”为单位)分别是: 2,3,5,8,13,21,34,55,89,144,233,377 (0) 原来的一对新生一对 (1月底) 原来的一对新生一对 (2月底) 新生一对新生一对 (3月底) 图3-8 所以,问题的答案是,从一对有生殖能力的兔子开始,整整一年之后,兔子的总数将有377对。

裴波那契发现,这一连串数目之间有一个简单的规律:将其中任何一个数与它后面一个数相加,结果等于再后面的一个数。 例如,2+3=5 3+5=8 5+8=13 …… 等等。他指出,利用这个规律,可以无限继续推算下去。 如果另外一户人家,买回去一对刚出生的小兔子,那么这一家在每个月的月底盘点,成对兔子的数目排成的数列是 1,1,2,3,5,8,13,21,34,55,89,144,233,377 ……… ① 数列①叫做斐波那契数列,可用公式 ???=+===--)5,4,3(1,12121 n a a a a a n n n ② 求该数列的每一项。 (二)递推与迭代 斐波那契数列的中求每一项的公式②给出的是数列中的一个递推式,从中可以看出,所谓“递推”,是指在前面一个或几个结果的基础上推出下一个结果。解决递推问题必须具备两个要求:(1)初始条件;(2)递推关系(或递推公式)。在上面的问题中,初始条件为 1,121==a a 递推关系为 )5,4,3(21 =+=--n a a a n n n 合起来就表示为公式 ???=+===--) 5,4,3(1,12121 n a a a a a n n n 数列中有许多问题没有现成的公式直接求出结果,而必须采用递推的方法一步一步地推出最后的结果。在斐波那契数列中当n≥3时因为没有任何现成的公式能直接求出第n 个数,用循环程序来处理这个问题是比较容易的。 【basic 程序一】 a1=1

相关文档
最新文档