关于递归与递推的那七道题
递推数列试题及答案
递推数列试题及答案1. 已知递推数列 \(a_n\) 满足 \(a_1 = 2\),\(a_{n+1} = 2a_n + 1\),求 \(a_5\) 的值。
答案:首先,我们根据给定的递推公式计算数列的前几项。
\(a_1 = 2\)\(a_2 = 2a_1 + 1 = 2 \times 2 + 1 = 5\)\(a_3 = 2a_2 + 1 = 2 \times 5 + 1 = 11\)\(a_4 = 2a_3 + 1 = 2 \times 11 + 1 = 23\)\(a_5 = 2a_4 + 1 = 2 \times 23 + 1 = 47\)所以,\(a_5\) 的值为 47。
2. 给定递推数列 \(b_n\) 满足 \(b_1 = 3\),\(b_{n+1} = 3b_n - 2\),求 \(b_4\) 的值。
答案:同样地,我们使用递推公式计算数列的前几项。
\(b_1 = 3\)\(b_2 = 3b_1 - 2 = 3 \times 3 - 2 = 7\)\(b_3 = 3b_2 - 2 = 3 \times 7 - 2 = 19\)\(b_4 = 3b_3 - 2 = 3 \times 19 - 2 = 55\)因此,\(b_4\) 的值为 55。
3. 考虑递推数列 \(c_n\) 满足 \(c_1 = 1\),\(c_{n+1} = c_n + n\),求 \(c_4\) 的值。
答案:我们根据递推公式计算数列的前几项。
\(c_1 = 1\)\(c_2 = c_1 + 1 = 1 + 1 = 2\)\(c_3 = c_2 + 2 = 2 + 2 = 4\)\(c_4 = c_3 + 3 = 4 + 3 = 7\)所以,\(c_4\) 的值为 7。
4. 递推数列 \(d_n\) 满足 \(d_1 = 5\),\(d_{n+1} =\frac{d_n}{2} + 1\),求 \(d_3\) 的值。
关于递归的一些小练习
关于递归的⼀些⼩练习递归什么是递归在程序中, 所谓的递归, 就是函数⾃⼰直接或间接的调⽤⾃⼰.1. 直接调⽤⾃⼰2. 间接调⽤⾃⼰就递归⽽⾔最重要的就是跳出结构. 因为跳出了才可以有结果.所谓的递归就是化归思想递归的调⽤, 写递归函数, 最终还是要转换为⾃⼰这个函数.假如有⼀个函数 f, 如果它是递归函数的话, 那么也就是说函数体内的问题还是转换为 f 的形式.递归思想就是将⼀个问题转换为⼀个已解决的问题来实现function f() {... f( ... ) ...}例⼦: 1, 2, 3, 4, 5, ..., 1001. ⾸先假定递归函数已经写好, 假设是 foo. 即 foo( 100 ) 就是求 1 到 100 的和2. 寻找递推关系. 就是 n 与 n-1, 或 n-2 之间的关系: foo( n ) == n + foo( n - 1 )var res = foo( 100 );var res = foo( 99 ) + 100;3. 将递推结构转换为递归体function foo( n ) {return n + foo( n - 1 );}* 将求 100 转换为求 99* 将求 99 转换为求 98* ...* 将求 2 转换为求 1* 求 1 结果就是 1* 即: foo( 1 ) 是 14. 将临界条件加到递归体中function foo( n ) {if ( n == 1 ) return 1;return n + foo( n - 1 );}练习: 求 1, 3, 5, 7, 9, ... 第 n 项的结果与前 n 项和. 序号从 0 开始求第 n 项的1. ⾸先假定递归函数已经写好, 假设是 fn. 那么第 n 项就是 fn( n )2. 找递推关系: fn( n ) == f( n - 1 ) + 23. 递归体function fn( n ) {return fn( n-1 ) + 2;}4. 找临界条件求 n -> n-1求 n-1 -> n-2...求 1 -> 0求第 0 项, 就是 15. 加⼊临界条件function fn( n ) {if ( n == 0 ) return 1;return fn( n-1 ) + 2;}前n项和1. 假设已完成, sum( n ) 就是前 n 项和2. 找递推关系: 前 n 项和等于第 n 项 + 前 n-1 项的和3. 得到递归体function sum( n ) {return fn( n ) + sum( n - 1 );}4. 找临界条件n == 1 结果为 15. 得到递归函数function sum( n ) {if ( n == 0 ) return 1;return fn( n ) + sum( n - 1 );}练习: 2, 4, 6, 8, 10 第 n 项与前 n 项和第n项function fn( n ) {if ( n == 0 ) return 2;return fn( n-1 ) + 2;}前n项和function sum( n ) {if ( n == 0 ) return 2;return sum( n - 1 ) + fn( n );}练习: 数列: 1, 1, 2, 4, 7, 11, 16, … 求第 n 项, 求前 n 项和.求第 n 项1. 假设已经得到结果 fn, fn( 10 ) 就是第 10 项2. 找递推关系0, 1 => fn( 0 ) + 0 = fn( 1 )1, 2 => fn( 1 ) + 1 = fn( 2 )2, 3 => fn( 2 ) + 2 = fn( 3 )...n-1, n => fn( n-1 ) + n - 1 = fn( n )3. 递归体也就清楚了, 临界条件是 n == 0 => 1function fn( n ) {if ( n == 0 ) return 1;return fn( n-1 ) + n - 1;}如果从 1 开始表⽰, 那么第 n 项为1. 假设已经得到结果 fn, fn( 10 ) 就是第 10 项2. 找递推关系1, 2 => fn( 1 ) + 0 = fn( 2 )2, 3 => fn( 2 ) + 1 = fn( 3 )3, 4 => fn( 3 ) + 2 = fn( 4 )...n-1, n => fn( n-1 ) + n - 2 = fn( n )3. 临界条件 n == 1 => 1前n项和function sum( n ) {if ( n == 0 ) return 1;return sum( n - 1 ) + fn( n );}如果从 0 开始0 1 2 3 4 5 61, 1, 2, 4, 7, 11, 16,如果从 1 开始1 2 3 4 5 6 71, 1, 2, 4, 7, 11, 16,练习: Fibonacci 数列: 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, …求其第 n 项.递推关系 fn(n) == fn( n- 1) + fn( n - 2)function fib( n ) {if ( n == 0 || n == 1 ) return 1;return fib( n - 1 ) + fib( n - 2 );}阶乘阶乘是⼀个运算, ⼀个数字的阶乘表⽰的是从 1 开始累乘到这个数字. 例如 3! 表⽰1 * 2 * 3. 5! 就是1 * 2 * 3 * 4 * 5. 规定 0 没有阶乘, 阶乘从 1 开始.求 n 的阶乘function foo ( n ) {if ( n == 1 ) return 1;return foo( n - 1 ) * n;}求幂求幂就是求某⼀个数⼏次⽅2*2 2 的平⽅, 2 的 2 次⽅求 n 的 m 次⽅最终要得到⼀个函数 power( n, m )n 的 m 次⽅就是 m 个 n 相乘即 n 乘以 (m-1) 个 n 相乘function power ( n, m ) {if ( m == 1 ) return n;return power( n, m - 1 ) * n;}深拷贝如果要实现深拷贝那么就需要考虑将对象的属性, 与属性的属性, ... 都拷贝过来如果要实现:1. 假设已经实现 clone( o1, o2 ), 将对象 o2 的成员拷贝⼀份交给 o12. 简单的算法, 将 o2 的属性拷贝到 o1 中去function clone( o1, o2 ) {for ( var k in o2 ) {o1[ k ] = o2[ k ];}}3. 找递推关系, 或叫划归为已经解决的问题假设⽅法已经实现, 问⼀下, 如果 o2[ k ] 是对象继续使⽤这个⽅法因此需要考虑的是 o2[ k ] 如果是引⽤类型, 再使⽤⼀次 clone() 函数如果 o2[ k ]不是引⽤类型, 那么就直接赋值function clone( o1, o2 ) {for ( var k in o2 ) {if ( typeof o2[ k ] == 'object' ) {o1[ k ] = {};clone( o1[ k ] , o2[ k ] );} else {o1[ k ] = o2[ k ];}}}复杂实现: clone( o ) -> newObjfunction clone( o ) {var temp = {};for ( var k in o ) {if ( typeof o[ k ] == 'object' ) {temp[ k ] = clone( o[ k ] );} else {temp[ k ] = o[ k ];}}return temp;}请⽤递归实现 getElementsByClassName<div><div>1<div class="c">2</div><div>3</div></div><div class="c">4</div><div>5<div>6</div><div class="c">7</div></div><div>8</div></div>1. 如果实现⼀个⽅法 byClass( node, 'c', list ), 表⽰在某⼀个节点上查找符合 class 属性为 c 的元素2. 在当前元素的⼦元素中查找, 如果有符合要求的, 存储到⼀个数组中3. ⾸先遍历⼦节点, 然后看⼦节点是否还有⼦节点, 如果没有直接判断, 如果有再递归function byClass( node, className, list ) {var arr = node.childNodes;for ( var i = 0; i < arr.length; i++ ) {if ( arr[ i ].className == className ) {list.push( arr[ i ] );}if ( arr[ i ].childNodes.length > 0 ) {byClass( arr[ i ], className, list );}}}。
《算法设计与分析》递归算法典型例题
2. 算法构造
设皇帝有 count 个王子,
property[count]=count;
for (i=count-1; i>=1; i--)
{
if (property[i+1]%9!=0 )
break;
// 数目不符跳出 for 循环
else
property[i]=property[i+1]*10/9+i; //计算到第 i 个王子时剩余份数
四、 实验过程
(一) 题目一:…… 1. 题目分析 由已知可得,运动会最后一天剩余的金牌数 gold 等于运动会举行的天数由此可倒推每一 天的金牌剩余数,且每天的金牌数应为 6 的倍数。 2. 算法构造 设运动会举行了 N 天, If(i==N)Gold[i]=N; Else gold[i]=gold[i+1]*7/6+i;
3. 算法实现
#include <iostream> // 预编译命令
using namespace std;
void main()
//主函数
{
int i=0;
int num[9];
//定义储存数组
num[8]=6;
//到终点站车上还有六人
for(i=7; i>=2; i--)
num[i]=2*(num[i+1]-8+i); //计算到第 i 站车上的人数
//主函数
{
int i=0;
int fish[6];
//定义储存数组各天剩余金鱼数
fish[5]=11;
for (i=4; i>=1; i--)
fish[i]=(fish[i+1]*(i+1)+1)/i; //计算到第 i 天剩余金鱼条数
递归的经典例子
递归的经典例子
1. 算数学题的时候啊,像计算一个数的阶乘,这就是一个递归的经典例子呀!比如说计算 5 的阶乘,不就是 5 乘以 4 的阶乘嘛,而 4 的阶乘又等于 4 乘以 3 的阶乘,依次类推,这多有意思啊!
2. 还有走迷宫呢,你想想,当你在迷宫里遇到岔口,你选择一条路走,然后又遇到岔口,又继续选择,这不就跟递归很像嘛!你不断地进入更小的问题去探索,直到找到出口,这难道不是很神奇吗?
3. 画树也可以用递归呀!先画一个树干,然后树干上又分出树枝,每个树枝又可以当作新的树干去继续分树枝,这不就跟递归的过程一样嘛,哇塞,这样就能画出一棵复杂又漂亮的树啦!
4. 你知道汉诺塔游戏不?那就是典型的递归例子哟!要把盘子从一个柱子移到另一个柱子,不就得不断地用递归的方法去解决嘛,天啊,真是好烧脑又好有趣!
5. 再来说说我们电脑里的文件系统,那也是递归的体现呀!文件夹里有子文件夹,子文件夹里还有子文件夹,就这么一层层下去,像不像递归在大展身手呢?
6. 回忆一下我们看电影的时候,很多故事里不是也有类似递归的情节嘛!主角解决一个问题又引出新的问题,然后一直这么循环,这也可以说是一种故事里的递归呀,多有意思的发现呀!
总之,递归在生活中无处不在,它就像一把神奇的钥匙,能打开很多复杂问题的大门,给我们带来惊喜和挑战!。
递归递推区别分析与例题总结
递归递推区别分析与例题总结递归与递推⽂章⽬录特点递归(recursive)运⾏过程中⾃我调⽤,求解过程分为回溯和递推两个过程,占⽤内存多(栈数先积累后收缩,有可能爆栈),代码简洁但低效。
尾递归和递归区别⬇function story() {从前有座⼭,⼭上有座庙,庙⾥有个⽼和尚,⼀天⽼和尚对⼩和尚讲故事:story() // 尾递归,进⼊下⼀个函数不再需要上⼀个函数的环境了,得出结果以后直接返回。
}function story() {从前有座⼭,⼭上有座庙,庙⾥有个⽼和尚,⼀天⽼和尚对⼩和尚讲故事:story(),⼩和尚听了,找了块⾖腐撞死了 // ⾮尾递归,下⼀个函数结束以后此函数还有后续,所以必须保存本⾝的环境以供处理返回值。
}尾递归省内存、⾼效(相当于(或者说递推?))Python⽆法在语⾔中实现尾递归优化(Tail Call Optimization, TCO),所以采⽤了for, while等特殊结构代替recursive的表述(优化是编译器⼲的,发现尾递归结构就给优化了)。
递推(iterative)效率⽐递归⾼,尽量递推,除⾮只能递归。
例题递推例⼦⼀般都是数学题。
重点是找递推公式(也太好偷懒了吧)平⾯分割问题直线分割平⾯(基本结论)如果当前有 n 条直线,新增加⼀条直线(第 n+1 条直线),可以多出来 n 个交点(新的直线和之前所有的直线都有交点),⽽多出来 n 个交点对应到可以多出 n+1 个平⾯(⽐如从两条线,⼜新增⼀条线时,新的线和两条线都相交,作⽤在三个区域上,对这三个区域切分,增加三个平⾯)。
也即:S n+1=S n+(n+1)=1+(n+1)(n+2)2当平⾯上已有n-1条曲线将平⾯分割成a n-1个区域后,第n-1条曲线每与曲线相交⼀次,就会增加⼀个区域,因为平⾯上已有了n-1条封闭曲线,且第n条曲线与已有的每⼀条闭曲线恰好相交于两点,且不会与任两条曲线交于同⼀点,故平⾯上⼀共增加2(n-1)个区域,加上已有的a n-1个区域,⼀共有a n-1+2(n-1)个区域。
递推与递归练习题
}
getch();
}
3.#include <stdio.h>
#include <stdlib.h>
#define N 30
void main()
{
int n, si,si1;
si1=1;
for(n=N-1;n>=1;n--)//倒数第二天开始
{
si=(si1+1)*2; //算出当天的桃子数
{
if(Duhe(a,b+2,0)==1)
return 1;
}
if(judge(a+2,b,1-a,3-b,0))
{
if(Duhe(a+2,b,0)==1)
return 1;
}
if(judge(a+1,b,2-a,3-b,0))
{
if(Duhe(a+1,b,0)==1)
return 1;
}
if(judge(a,b+1,3-a,2-b,0))
{ /*则判断下一个状态,直至问题解决*/
if(a==0&&b==0) return 1;
if(n==0) /*判断0状态时,商匪状态是否符合要求*/
{
if(judge(a-1,b-1,4-a,4-b,1))
{
if(Duhe(a-1,b-1,1)==1)
return 1;
}
if(judge(a,b-2,3-a,5-b,1))
2.(用递归做)商人渡河问题是这样的:有三个商人,三个强盗,和一条船(船每次只可以载小于等于两个人)他们同在河的一边,想渡过河去,但是必须保证在河的任何一边必须保证商人的数目大于等于强盗的数目,应该怎么过这条河呢?
递归经典题目
递归经典题目
递归是一种常用的算法技术,它可以用来解决许多经典问题。
以下是一些经典的递归问题:
1. 斐波那契数列:这是一个经典的递归问题,其中每个数字是前两个数字的和。
例如,斐波那契数列的前几个数字是 0、1、1、2、3、5、8、13、21 等。
2. 阶乘函数:这是一个计算一个数的阶乘的递归函数。
例如,5 的阶乘是 5 4 3 2 1 = 120。
3. 汉诺塔问题:这是一个经典的递归问题,其中有一些盘子需要从一根柱子移动到另一根柱子,每次只能移动一个盘子,并且不能将一个较大的盘子放在较小的盘子上面。
4. 二分搜索:这是一个在排序数组中查找特定元素的递归算法。
它首先将数组分成两半,然后根据目标值与中间元素的比较结果,选择另一半继续搜索。
5. 回溯算法:这是一种通过递归搜索所有可能解的算法,通常用于解决约束满足问题。
例如,排列组合问题、八皇后问题等。
6. 分治算法:这是一种将问题分解为更小的子问题,然后递归地解决这些子问题的算法。
例如,归并排序和快速排序等。
7. 动态规划:这是一种使用递归和备忘录(或称为记忆化)的方法,用于解决具有重叠子问题和最优子结构的问题。
例如,背包问题和最短路径问题等。
这些经典的递归问题涵盖了不同的应用领域和算法类型,可以通过学习和解决这些问题来提高自己的编程和算法技能。
递归与递推
递推与递归练习题1、过河卒(NOIP2002普及组第4题)【问题描述】棋盘上A点有一个过河卒,需要走到目标B点。
卒行走的规则:可以向下、或者向右。
同时在棋盘上C点有一个对方的马,该马所在的点和所有跳跃一步可达的点称为对方马的控制点。
因此称之为“马拦过河卒”。
棋盘用坐标表示,A点(0, 0)、B点(n, m)(n, m为不超过15的整数),同样马的位置坐标是需要给出的。
现在要求你计算出卒从A点能够到达B 点的路径的条数,假设马的位置是固定不动的,并不是卒走一步马走一步。
输入:一行四个数据,分别表示B点坐标和马的坐标。
输出:一个数据,表示所有的路径条数。
【样例输入】knight.in6 6 3 3【样例输出】knight.out6【问题分析】跳马是一道老得不能再老的题目,每位编程者都学过,一般是在学习回溯或搜索算法时,很多书上也有类似的题目,一些比赛中也经常出现这一问题的变形(如NOIP1997初中组第三题)。
有些同学一看到这种类型的题目就去盲目搜索,但事实证明:当n,m=15就会超时。
其实,对本题稍加分析就能发现,到达棋盘上的一个点,只能从左边过来(我们称之为左点)或是从上面过来(我们称之为上点)。
根据加法原理,到达某一点的路径条数,就等于到达其相邻的上点或左点的路径数目总和。
因此我们可以使用逐列(逐行)递推的方法来求出从起点到终点的路径数目。
障碍点(马的控制点)也完全适用,只要将到达该点的路径数目设置为0即可。
假设用F[I,J]到达点(I,J)的路径数目用G[I,J]表示点(I,J)是否为对方马的控制点,G[I,J]=0表示不是对放马的控制点,G[I,J]=1表示是对方马的控制点。
则,我们可以得到如下的递推关系式:F[I,J]=0 {G[I,J]=1}F[I,0]=F[I-1,0] {I>0,G[I,0]=0}F[0,J]=F[0,J-1] {J>0,G[0,J]=0}F[I,J]=F[I-1,J]+F[I,J-1] {I>0,J>0,G[I,J]=0}上述递推式边界是:F[0,0]:=1。
递归练习题(打印版)
递归练习题(打印版)### 递归练习题(打印版)#### 一、递归基础概念题1. 定义题:请简述什么是递归,并给出递归的基本形式。
2. 判断题:以下哪些函数是递归的?- A. `f(x) = x + 1`- B. `g(n) = n * g(n-1)` (n > 0)- C. `h(x) = x * h(x-1)` (x > 1)3. 简答题:递归和迭代有什么区别?#### 二、递归函数编写题1. 编写递归函数:编写一个递归函数,实现阶乘计算。
2. 编写递归函数:编写一个递归函数,实现斐波那契数列的第n项。
3. 编写递归函数:编写一个递归函数,实现汉诺塔问题的解决方案。
#### 三、递归算法应用题1. 应用题:如何使用递归算法解决归并排序问题?2. 应用题:使用递归算法解决二叉树的深度优先搜索(DFS)。
3. 应用题:描述如何使用递归算法实现图的深度优先搜索(DFS)。
#### 四、递归优化题1. 优化题:对于递归算法,如何避免重复计算?2. 优化题:请解释尾递归优化的概念,并给出一个尾递归的例子。
3. 优化题:如何使用记忆化递归(Memoization)来优化递归算法?#### 五、递归问题解决题1. 问题解决题:给定一个数字n,请使用递归算法找出n的二进制表示中1的个数。
2. 问题解决题:使用递归算法实现一个函数,判断一个字符串是否是回文。
3. 问题解决题:给定一个整数数组,使用递归算法找出数组中的最大值。
#### 六、递归思维拓展题1. 思维拓展题:递归算法在解决哪些类型的问题时特别有效?2. 思维拓展题:在编程中,递归算法有哪些潜在的缺点?3. 思维拓展题:请讨论递归算法在人工智能领域的应用。
#### 七、递归实践题1. 实践题:实现一个递归函数,用于计算组合数C(n, k)。
2. 实践题:编写一个递归函数,实现快速排序算法。
3. 实践题:给定一个字符串,使用递归算法实现字符串的反转。
递归问题经典
几个经典的递推或递归问题猴子分桃海滩上有一堆桃子,五只猴子来分。
第1只猴子把这堆桃子平均分为五份,多了一个,这只猴子把多的一个吃掉,拿走了一份。
第二只猴子把剩下的桃子又平均分为五份,又多了一个,它同样把多的一个吃掉,拿走了一份,第3、第4、第5只猴子都是这样做的。
问海滩上原来最少有多少个桃子?汉诺塔问题汉诺塔问题又称河内塔问题,是源于印度一个古老传说的益智玩具。
大梵天创造世界的时候做了三根金刚石柱子,在一根柱子上从下往上按照大小顺序摞着64片黄金圆盘。
大梵天命令婆罗门把圆盘从下面开始按大小顺序重新摆放在另一根柱子上。
并且规定,在小圆盘上不能放大圆盘,在三根柱子之间一次只能移动一个圆盘,按此规则完成所有圆盘从一根柱子搬到另一根柱子上时即是世界末日,假定将一个圆盘移到另一根柱子上用时1秒,问整个搬完用时几何?下图分析圆盘数目为3时的情况,可通过其观察移动的一般规律。
2-涂色问题例对于1×n表格,用黑白两色对方格任意涂色,但是任何两个黑格不可以相邻,求不同的涂色方法数。
a 1=2,an=3,,an=an-1+an-2偶数个数码1的n位数用1,2,3,4这四个数字,可以组成多少个含有偶数个1的n位数?a 1=3,an=(4n-1-an-1)+3an-1天平需要多少种不同的操作过程?例*设n是一个给定的正整数,有一个天平以及n个质量分别为20,21,22,23,24,……,2n-1的砝码,现在通过n次操作逐个将所有的砝码都放上天平,每次操作都是将一个尚未放上天平的砝码放在天平的左边或者右边,并且天平的右边质量始终不超过天平左边的质量。
问有多少种不同的操作过程?a 1=1,an=(2n-1)an-1,an=(2n-1)!!1988年IMO加拿大训练题例由0,1,2这3个数组成长为n的序列,其中0和2不相邻,但0可排首位,问有多少个不同的序列? s1=3,s2=7, s n+1=2s n+s n-1美国中学奥赛题正整数的n(n>1)进制表示中,各位数字各不相同,且每个数字均与相邻数字相差(大数减小数)1,这样的正整数有多少个?a 1=1,an=bn-(n-1) , an=2n+1-n-2第229页设广义的(首位为0的)满足条件的n进制数有bn个b n+1=2bn+n+1。
递归练习题目
1.求阶乘.输入n(0<n<50), 求n!并输出.2.Fibonacci数列问题描述:Fibonacci兔子问题是个经典问题:从某天开始把雌雄各一的一对小兔子放入养殖场中,小兔经过一个月长大,长大后,雌兔每月产雌雄各一的一对小兔。
每对新兔也是一个月长大,长大后每对新兔也是每月产一对兔子。
试问第n个月养殖场共有多少对兔子。
输入: n ,表示第n个月;输出: 输出从第一个月到第n个月的兔子数目的序列.样例: n=5输出: 1 1 2 3 53、Hanoi问题(汉诺塔)。
有n个圆盘,半径各不相同,依半径从大到小,自下而上套在A柱上,另还有B、C 两根空柱,现要求将A柱上的n个圆盘全部搬到C柱上去且每次只许搬动一个盘子,还必须始终保持每根柱子上是小盘在上,大盘在下。
编一个程序能够打印出移动过程。
4.棋子移动。
有2n个棋子(n>=4)排成一行,开始位置为白子全部在左边,黑子全部在右边,如图(n=5):〇〇〇〇〇●●●●●移动棋子的规则是:每次必须同时移动移动相邻两个棋子,颜色不限,可以左移也可以右移到空位上去,但不能调换两个棋子的左右位置。
每次移动必须跳过若干个棋子(不能平移),要求最后能移成黑白相间的一行棋子。
如n=5时,成为:〇●〇●〇●〇●〇●5、字母排列(组合)显示从前m(A-----第m个)个大写英文字母中取n个不同字母的所有排列(组合)。
6、自然数拆分一个整数n(n<=100)可以有多种分划,使其分划的一列整数之和为n。
例如:输入:n=6输出文件hs.out,格式内容为65 14 24 1 13 33 2 13 1 1 12 2 22 2 1 12 1 1 11 1 1 1 1 1total=11 {表示分划数有11种}7、数的一半(vijos 1130)要求找出具有下列性质的数的个数(包含输入的自然数n):先输入一个自然数n(n<=500),然后对此自然数按照如下方法进行处理:①. 不作任何处理;②. 在它的左边加上一个自然数,但该自然数不能超过原数的一半;③. 加上数后,继续按此规则进行处理,直到不能再加自然数为止.样例: 输入: 6满足条件的数为 6162612636136输出: 68、核电站问题(vijos 1232)一个核电站有N个放核物质的坑,坑排列在一条直线上。
递归算法经典题目
递归算法经典题目递归算法是一种非常强大的编程技术,它能够解决一些复杂的问题,将它们分解为更小的子问题。
以下是一些经典的递归算法题目:1. 斐波那契数列:这是一个经典的递归问题,斐波那契数列中的每个数字都是前两个数字的和。
例如,0, 1, 1, 2, 3, 5, 8, 13, 21... 编写一个函数来计算斐波那契数列中的第n个数字。
2. 阶乘:阶乘是一个数的所有小于及等于该数的正整数的乘积。
例如,5的阶乘(记作5!)是5 4 3 2 1 = 120。
编写一个函数来计算一个数的阶乘。
3. 二分搜索:二分搜索是一种在排序数组中查找特定元素的搜索算法。
编写一个函数,该函数使用二分搜索在给定的排序数组中查找特定的元素。
4. 回溯算法:回溯算法用于解决决策问题,例如八皇后问题。
在这个问题中,我们需要在一个8x8棋盘上放置8个皇后,使得任何两个皇后都不在同一行、同一列或同一对角线上。
编写一个使用回溯算法解决八皇后问题的函数。
5. 合并排序:合并排序是一种分治算法,它将一个大的列表分成两个较小的子列表,对子列表进行排序,然后将它们合并成一个已排序的列表。
编写一个使用递归实现合并排序的函数。
6. 快速排序:快速排序也是一种分治算法,它选择一个"基准"元素,然后将所有比基准小的元素放在其左边,所有比基准大的元素放在其右边。
然后对左右两个子列表进行快速排序。
编写一个使用递归实现快速排序的函数。
7. 深度优先搜索(DFS):这是一种用于遍历或搜索树或图的算法。
这个算法会尽可能深地搜索树的分支。
当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。
这一过程一直进行到已发现从源节点可达的所有节点为止。
如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。
编写一个使用递归实现深度优先搜索的函数。
这些题目都可以帮助你理解和应用递归算法。
递归与递推练习
递规与递推练习杨辉三角形(Triangle)【程序名称】triangle.exe【源程序名】triangle.(pas/c/cpp)【输入文件】triangle.in【输出文件】triangle.out【问题描述】有一个数字三角是我国古代著名数学家杨辉首先提出的,这个数字三角如下图所示:11 11 2 11 3 3 11 4 6 4 1……现在给你一个正整数n,请你用递归算法给出杨辉的前n行。
【输入数据】输入文件共一行,包含一个正整数n(1≤n≤20)。
【输出数据】输出文件共n行,即杨辉三角的前n行。
每行包含若干正整数,这些正整数之间用一个空格隔开(不能有多余的空格),最后一个正整数后面没有空格。
【样例】triangle.in4triangle.out11 11 2 11 3 3 1多米诺骨牌(Domino)【程序名称】domino.exe【源程序名】domino.(pas/c/cpp)【输入文件】domino.in【输出文件】domino.out【问题描述】有N块1×2大小的骨牌需要放入一个2×N的牌盒中,请问共有多少种放法(输出总放法数的最后100位即可)。
【输入数据】输入数据仅一个自然数N(N≤106)。
【输出数据】输出数据共4行,每行25位,共100位。
表示总放法数的最后100位。
不满100位时高位用0补足。
【样例】domino.in5domino.out0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000008走楼梯(Stairs)【程序名称】stairs.exe【源程序名】stairs.(pas/c/cpp)【输入文件】stairs.in【输出文件】stairs.out【问题描述】有一楼梯共N阶,由于年久失修,其中有K阶台阶已经损坏(人不能在损坏的台阶上停留),已知某人一次能上一阶、两阶或三阶台阶,请问,此人从楼梯底部走到楼梯顶部,共有多少种走法。
递推和递归
递推算法以初始{起点}值为基础,用相同的运算规 律,逐次重复运算,直至运算结束。这种从“起点” 重复相同的方法直至到达一定“边界”,犹如单向 运动,用循环可以实现。递推的本质是按规律逐次 推出(计算)下一步的结果。
递归解法
函数 Function num(x:integer):integer; begin if x=5 then num:=10; else num:=num(x+1)+2; end; Begin writeln(num(1)); 过程 Var a: integer; Procedure Num(x: integer); begin if x=5 then a:=10 else begin Num(x+1); a:=a+2 end; end; begin Num(1); writeln(’The Num is ’, a); readln end.
End.
练习题
1. 求斐波那契数列:0,1,1,2,3,5,8,13,21…的第 n项。 2.楼梯有N阶台阶,上楼可以一步上一阶,也可以一步两阶。 编程计算有多少种走法。例如:输入N=2,输出m=2.
①a5=10; ②a4=a5+2=12; ③a3=a4+2=14; ④a2=a3+2=16; ⑤a1=a2+2=18;
begin a:=10; {以第五位同学的棵数为递推的起始值} for i :=1 to 4 do {还有4人,递推计算4次} a:= a+2; {递推运算规律} writeln(’The Num is’, a); readln; end.
递推和递归算法
萍乡中学 何永明
[例1] 植树节那天,有五位参加了植树活动,他们完成植树的棵数都不相 同。问第一位同学植了多少棵时,他指着旁边的第二位同学说比他多 植了两棵;追问第二位同学,他又说比第三位同学一位同学多植两棵。 最后多植了两棵;…如此,都说比另问到第五位同学时,他说自己植 了10棵。到底第一位同学植了多少棵树? 解:设第一位同学植树的棵数为a1,欲求a1,需从第五位同学植树的棵 数a5入手,根据“多两棵”这个规律,按照一定顺序逐步进行推算 :
递推习题——精选推荐
1、走楼梯【问题描述】楼梯有n级台阶,上楼可以一步上一个台阶,也可以一步上两个台阶。
编写一个递归程序,计算共有多少种不同的走法?【输入样例】3【输出样例】32、兔子繁殖【问题描述】有一种兔子,出生后一个月就可以长大,然后再过一个月一对长大的肚子就可以生育一对小兔子且以后每个月都能生育一对。
现在,我们有一对刚出生的这种兔子,那么,n个月后,我们会有多少对兔子呢?假设所有的兔子都不会死亡。
【输入格式】仅一行,包含一个自然数n。
【输出格式】仅一行,包含一个自然数,即n个月后兔子的对数。
【输入样例】5【输出样例】53、平面切割【问题描述】同一个平面内有n(n≤500)条直线,已知其中p(p≥2)条直线相交于同一点,则这n条直线最多能将平面分割成多少个不同的区域?【输入格式】两个整数n(n n≤500)和p(2≤p≤n)。
【输出格式】一个正整数,代表最多分割成的区域数目。
【输入样例】12 5【输出样例】734、蜜蜂路线【问题描述】一只蜜蜂在下图所示的数字蜂房上爬动,已知它只能从标号小的蜂房爬到标号大的相邻蜂房,现在问你:蜜蜂从蜂房m开始爬到蜂房n,m<n,有多少种爬行路线?【输入格式】仅一行,包含两个自然数m,n。
【输出格式】仅一行,包含一个自然数,即爬行路线的种数。
【输入样例】1 14【输出样例】3775、数塔问题【问题描述】设有一个三角形的数塔,顶点为根结点,每个结点有一个整数值。
从顶点除法,可以向左下走或向右下走,如图所示:若要求从根结点开始,找出一条路径,使路径之和最大,只要输出路径之和的最大值。
【输入格式】第一行为n(n<10),表示数塔的层数。
第二行到n+1行,每行有若干个数据,表示数塔中的数值。
【输出格式】一个数据,即路径之和的最大值。
【输入样例】51311 812 7 266 14 15 812 7 13 24 11【输出样例】866、贮油点【问题描述】一辆重型卡车欲穿过1000公里的沙漠,卡车耗油为1升/公里,卡车总载油能力为500公升。
递规与递推习题汇总
递规与递推习题汇总2.1 遍历问题我们都很熟悉二叉树的前序、中序、后序遍历,在数据结构中常提出这样的问题:已知一棵二叉树的前序和中序遍历,求它的后序遍历,相应的,已知一棵二叉树的后序遍历和中序遍历序列你也能求出它的前序遍历。
然而给定一棵二叉树的前序和后序遍历,你却不能确定其中序遍历序列,考虑如下图中的几棵二叉树:a a a a/ / \ \b b b b/ \ / \c c c c所有这些二叉树都有着相同的前序遍历和后序遍历,但中序遍历却不相同。
【输入】输A数据共两行,第一行表示该二叉树的前序遍历结果s1,第二行表示该二叉树的后序遍历结果s2。
【输出】输出可能的中序遍历序列的总数,结果不超过长整型数。
【样例】trave1.in trave1.outabc 4bca【算法分析】根据二叉树先序遍历和后序遍历的特点,可以知道,先序遍历的第一个结点是后序遍历的最后一个结点,对于中序遍历来说却是中间的一个结点,这里所说的中间也只是相对而言的中间。
如果一棵二叉树的根结点没有左子树,那么先序遍历的第一个结点也是中序遍历的第一个结点,如果一棵二叉树的根结点没有右子树,那么先序遍历的第一个结点是中序遍历的最后一个结点。
我们这里还认为就是中序遍历的中间结点,上面两种情况只是特殊的情况。
设二叉树的结点总数为n(对于输入的字符串来说是它的长度),对于先序遍历的结果,第一个结点为根结点,从第二个结点到最后一个结点分为n种情况:根结点的左子树结点个数为n-1,右子树结点的个数为0;根结点的左子树结点个数为n-2,右子树结点的个数为1;……根结点的左子树结点个数为n-i,右子树结点的个数为i-1;{0<=i<=n-1);……根结点的左子树结点个数为0,右子树结点的个数为n-1。
根据这n种情况,分别将二叉树拆分为左子树和右子树,左子树结点个数为n-i,右子树结点的个数为i-l(0<=i<=n-1),先序遍历的结果是从第二个结点(字符)开始取,而后序遍历的结果里是从第1个结点字符开始取。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
关于递归与递推的那七道题
递归与递推是动态规划最底层的东西,掌握好它对于彻底的理解动规是至关重要的,这次做的题不难,但是它很能锻练人的思维,每一道题都有多种解法。
只要静下心来想,一般人都能做出来,而在做题的过程中,你会有很大的收获。
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]。
法三:
记住这个结论:2*n棋盘用多米诺牌完美覆盖的方法数为一个斐波那契数列,f[0] = f[1] = 1,
f[n] = f[n-1]+f[n-2]。
4、阿牛的EOF牛肉串
题目是这样的:
要构造一个长度为n的只由"E" "O" "F"三种字符组成的字符串(可以只有其中一种或两种字符,但绝对不能有其他字符),但是禁止在串中出现O相邻的情况,问总共有多少种构造方法。
这个题跟第2题一样,用记忆化搜索就可以把它搞定。
有牛人通过猜想,找规律也把它做出来了。
可以观察到,当n=1时,有f[n] = 3,当n=2时,有f[n] = 8,当n=3时,我们可以看出
f[n] = 22,由此找出规则f[n] = 2*(f[n-1] + f[n-2])。
用这个公式交上去,居然也对了。
至于证明嘛,我至今还没有想到。
5、6题都是关于错位排列的题目,求错位排列的个数的公式有很多个:
f[n] = n!(1-1/1!+1/2!-1/3!+……+(-1)^n*(1/n!));
f[n] = (n-1)(f[n-1]+f[n-2]);
f[n] = n*f[n-1]+(-1)^(n-2);
f[n]表示错位排列的个数。
上面三个公式都可以,就看哪个好用。
第6题稍微有点不同,它是求n 个数中有m个错位的排列的个数。
只须从这n 个中选出m个数来对它们错排,其余的数不动就行了。
7、求n条折线能够分割平面的最大数目。
我们知道n条直线能够分割平面的最大数目为n*(n+1)/2;
由这个公式,我们可以推出n条折线能够分割的平面的最大数目为2n*(2n+1)/2 – n = 2*n^2-n+1。
很好的递推题:铺磁砖和走格子
这是的递推专项训练的题目,感觉很好。
*题一:用1 x 1和2 x 2的磁砖不重叠地铺满N x 3的地板,共有多少种方案?
样例输入:2
样例输出:3
先设一个f[i]表示i*3的地板铺的方法,f[1]=1;f[2]=3;
i*3的地板数是这样得到的:(i-1)*3的地板比i*3的地板少的地方全铺上1*1的瓷砖,这有一种铺法;
或者在(i-2)*3的地板比i*3的地板少的地方铺上2*2的瓷砖和2个1*1的瓷砖,这有两种铺法;
所以得到递推式:f[i]=f[i-1]+2*f[i-2];
*题二:从原点出发,一步只能向右走、向上走或向左走。
恰好走N步且不经过已走的点共有多少种走法?
样例输入:2
样例输出:7
这个我没想出来,看题解才弄明白。
先设一个f[i]表示恰好走i步且不经过已走的点共有的走法。
如果向上走,不会出现经过已走的点;如果向左或右,上一步不能是向右或左。
引用题解上的一句话:/*
这一步的选择数= (3*上一步的所有选择中向上走的选择数) + (2*上一步的所有选择中向左、右走的选择数)。
上一步的所有选择中向上走的选择数”实际上就是“上上步的所有选择数”即d[i-2]
*/引用结束
还有一点,就是“上一步的所有选择中向左、右走的选择数” 等于“上步所有的选择数(即f[i-1])-上步向上的选择数”
也就等于“上步所有的选择数(即f[i-1])-上上步所有的选择数(即f[i-2])”所以得到递推式:f[i] = (3*f[i-2]) + 2*(f[i-1]-f[i-2]);
练习:
1、牛的繁殖问题。
有位科学家曾出了这样一道数学题:一头刚出生的小母牛从第四个年头起,每年初要生一头小母牛。
按此规律,若无牛死亡,第20年头上共有多少头母牛?
2、兔子繁殖(递推)
一对小兔子一年后长成大兔子;一对大兔子每半年生一对小兔子。
大兔子的繁殖期为4年,兔子的寿命是6年。
假定第一年年初投放了一对小兔子,试编程计算,第n年末总共会有多少对兔子。
n由键盘输入
这是一道关于递推的程序编程题目,但是找不到从问题的递推思路,知道思路的就写一下你的思路就可以了,不用写代码!!我只要知道一下思路就可以了·····
3、问题描述]
楼梯有n级台阶,上楼可以一步上一个台阶,也可以一步上两个台阶。
编写一递推程序,计算有多少种不同的走法?
4、现在有100个数按递推排列,其中第一个数是0,第二个数是2,并且从第二个数起每个数的三倍都等于前后两个数之和。
问第100个数被6除所得的余数是多少?。