一、算法思想:
递推法是把一个复杂的计算过程转化为简单过程的多次重复。因此又成为迭代法。递推分顺推和逆推两种。
递推是迭代算法中一种用若干步可重复的简单运算来描述复杂数学问题的方法,以便于计算机进行处理。由边界条件开始往后逐个推算,在一般情况下,效率较高,编程也非常的方便。但是,我们一般只需要求递推关系的第n项,而边界条件与第n项前面之间的若干项的信息是我们不需要的,如果采用递推的方法来求解的话,第n项之前的每一项都必须计算出来,最后才能得到所需要的第n项的值。这是递推无法避免的,从而在一定程度上影响了程序的效率。当然在大多数情况下,采用递推的方法还是可行的,在竞赛中,使用递推的方法编程,通常会在时限内出解。当然,更好的求解方法还有母函数法,迭代递推的方法,以后再讲。
二、入门:
1、逆推:http://acm.hdu.edu.cn/showproblem.php?pid=2013
顺着最后一天的挑子树依次推出前面几天的。
由于知道最后一天剩余一个桃子,则倒数第二天剩余(1+1)*2{4/2-1=1,它第二天吃了三个},第n天剩余(zong+1)*2;
两个代码的思想是一样的,第二个代码把逆推写成了顺推,其实吧,逆推顺推是一样的。
2、顺推: Fabonacci,关于斐波那契更多好题,陆续更新。
http://acm.hdu.edu.cn/showproblem.php?pid=1005
三、例题:
1、http://acm.hdu.edu.cn/showproblem.php?pid=1465
分析思路:
(1)当n=1和2时,易得解,假设f(n-1)和f(n-2)已经得到,重点分析下面的情况:
(2)当有n封信的时候,前面n-1封信可以有n-1或者n-2封错装。
(3)前者,对于每种错装,可从n-1封信中任意取一封和第n封错装,故=f(n-1)*(n-1)
(4)后者简单,只能是没装错的那封和第n封交换信封,没装错的那封可以是前面(n-1)封中的任意一个,故=f(n-2)*(n-1)
(5)递推公式:f[1]=0,f[2]=1,f[n]=(n-1)(f[n-1]+f[n-2]):著名的排错公式
2、http://acm.hdu.edu.cn/showproblem.php?pid=1297
分析思路:
(1)f(n)表示n个人的合法队列,则:按照最后一个人的性别分析,他要么是男,要么是女,所以可以分两大类讨论:
[1]如果n个人的合法队列的最后一个人是男,则对前面n-1个人的队列没有任何限制,他只要站在最后即可,所以,这种情况一共有f(n-1)
[2]如果n个人的合法队列的最后一个人是女,则要求队列的第n-1个人务必也是女生,这就是说,限定了最后两个人必须都是女生,这又可以分两种情况:
{1}如果队列的前n-2个人是合法的队列,则显然后面再加两个女生"f(n-2)+女",也一定是合法的,这种情况有f(n-2)
{2}但是、难点在于,即使前面n-2个人不是合法的队列,加上两个女生也有可能是合法的,当然,这种长度为n-2的不合法队列,不合法的地方必须是尾巴,就是说,这里说的长度是n-2的不合法串的形式必须是“f(n-4)+男+女”,这种情况一共有f(n-4)
(2)递推公式:f[1]=1,f[2]=2,f[3]=4,f[4]=7,f[n]=f[n-1]+f[n-2]+f[n-4]
(3)这道题要用到大数加法
3、青蛙过河
http://wenku.baidu.com/view/b15bcfeb551810a6f5248652.html
一条小溪尺寸不大,青蛙可以从左岸跳到右岸,在左岸有一石柱L,面积只容得下一只青蛙落脚,同样右岸也有一石柱R,面积也只容得下一只青蛙落脚。有一队青蛙从尺寸上一个比一个小。我们将青蛙从小到大,用1,2,……,n编号。规定初始时这队青蛙只能趴在左岸的石头L上,按编号一个落一个,小的落在大的上面。不允许大的在小的上面。在小溪中有S个石柱,有y片荷叶,规定溪中的柱子上允许一只青蛙落脚,如有多只,同样要求按编号一个落一个,大的在下,小的在上,而且必须编号相邻。对于荷叶只允许一只青蛙落脚,不允许多只在其上。当青蛙从左岸的L上跳走后就不允许跳回来;同样,从左岸L上跳至右岸R,或从溪中荷叶或溪中石柱跳至右岸R上的青蛙也不允许再离开。问在已知溪中有S根石柱和y片荷叶的情况下,最多能跳过多少只青蛙?
分析思路:
(1)先从个别再到一般,要善于对多个因素作分解,孤立出一个一个因素来分析,化难为易。
(2)定义函数jump(s,y)--最多可跳过河的青蛙数,s--河中柱子数,y--荷叶数
(3)当s=0,jump(0,y),当y=1时,jump(0,1)=2
第一步:1#跳到荷叶上
第二步:2#从L直接跳至R上
第三步:1#再从荷叶跳至R上
当y=2时,jump(0,2)=3
第一步:1#从L跳至叶1上
第二步:2#从L跳至叶2上
第三步:3#从L直接跳至R上
第四步:2#从叶2跳至R上
第五步:1#从叶1跳至R上
采用归纳法:jump(0,y)=y+1;
再看jump(s,y),先看一个最简单情况:s=1,y=1,jump(1,1)=4
第一步:1#L->Y
第二步:2#L->S
第三步:1#Y->S
第四步:3#L->Y
第五步:4#L->R
第六步:3#Y->R
第七步:1#S->Y
第八步:2#S->R
第九步:1#Y->R
jump(2,1)=8
1,1#L->Y
2,2#L->S1
3,1#Y->S1
4,3#L->Y
5,4#L->S2
6,3#Y->S2
7,2#S1->S2
8,1#S1->S2
9,5#L->Y
10,6#L->S1
11,5#Y->S1
12,7#L->Y
13,8#L->R
14,7#Y->R
15,5#S1->Y
16,6#S1->R
17,5#Y->R
18,1#S2->Y
19,2#S2->S1
20,1#Y->S1
21,3#S2->Y
22,4#S2->R
23,3#Y->R
24,1#S1->Y
25,2#S1->R
26,1#Y->R
考虑jump(s,y)与jump(s-1,y)的关系:jump(s,y)=2*jump(s-1,y)
dp:http://www.bianchengla.com/team/26/practise/problem?id=1007
4、五猴分桃
http://acm.zjgsu.edu.cn/JudgeOnline/problem.php?cid=1052&pid=0
5只猴子一起摘了一堆桃子,因为太累了,它们商量决定,先睡一觉再分。过了不知多久,来了一只猴子,它见别的猴子没来。它就将多的这个吃了,拿走其中一份。又过了不知多久,第2只猴子来了,它不知道有1个同伴已经来过,还以为自己是第一个到的呢,于是将地上的桃子堆起来,平均分成5份,发现也多了1个,同样吃了这1个,拿走其中1份。第3只,第4只……都是这样,问这5只猴子至少摘了多少个挑子?
(1)分析思路:递推+穷举
{1}递推
{2}递归
1020/(4/5)+1=1276
1276/(4/5)+1=1596
1596/(4/5)+1=1996
1996/(4/5)+1=2496
2496/(4/5)+1=3121
5、在一个平面上有一个圆和n条直线,这些直线中每一条在圆内同其他直线相交,假设没有3条直线相交于一点,试问这些直线将圆分成多少区域。
(1)分析思路:
当n=3时,圆内有n=3个交点,第4条线不与任何交点相交并且与其他3条线都相交,则第4条线成为了4个线段,每条线段分割一个区域则,则多出n个区域。
设n-1条直线分割形成的区域为f(n-1),新增的一条直线将穿过n个区域,使区域增加n,故
f(n)=f(n-1)+n
=f(n-2)+n-1+n
=f(0)+1+2+……+n-1+n
=n(n+1)/2+1
6、平面上有n条折线,问这些折线最多能将平面分割成多少块?
http://acm.hdu.edu.cn/showproblem.php?pid=2050
(1)分析思路:
{1}折线反向延伸就是相交线 ,n条相交线分割平面的块数最多为 F(n) =2n(2n+1)/2 +1
由于反向延伸而增加的平面数为 g(n)= 3+(n-1)2 -1 =2n
所以 f(n)= F(n)- g(n) =2n^2 -n +1
{2}f(n)=f(n-1)+4(n-1)+1
我们先从一条直线切割讲起,假如有N条直线,最多能把平面分成几部分?
我们知道当增加一条直线,要它和前面n-1条直线都相交,会产生n-1个交点,又由于每增加n个交点将增加n+1个平面,所以,n条直线最多将平面分成1+2+3+……+n=(n^2+n+2)/2
然后我们讨论n对平行线最多能将平面分成几块呢?
前面知道,当增加n对平行线时。例如:前面已经有2n-2条直线了,且在第2n-1条直线和2n条直线被添加时都会产生2n-2个交点,增加2n-1个平面,所以每次添加所增加的平面个数为2*(2n-1)=4n-2,所以我们得出n对平行线能将平面分成1+2+6+10+……+4n-2=2n*n+1
最后我们讨论n条直线能将平面分成几部分?其实折线,我们可以看成是两条平行线相交了,在纸上画一下我们就很容易发现当两条平行线相交后,原来它们所分的平面个数就会减少一个,故n条折线切割的平面数只要在n对平行线切割的平面基础上减去n即可,为2*n*n-n+1
7、设有n条封闭曲线画在平面上,而任何两条封闭曲线恰好相交于两点,且任何三条封闭曲线不相交于同一点,问这些封闭曲线把平面分割成的区域个数。
(1)分析思路:
设an为n条封闭曲线把平面分割成的区域个数。 由图2可以看出:a2-a1=2;a3-a2=4;a4-a3=6。从这些式子中可以看出an-an-1=2(n-1)。当然,上面的式子只是我们通过观察4幅图后得出的结论,它的正确性尚不能保证。下面不妨让我们来试着证明一下。当平面上已有n-1条曲线将平面分割成an-1个区域后,第n-1条曲线每与曲线相交一次,就会增加一个区域,因为平面上已有了n-1条封闭曲线,且第n条曲线与已有的每一条闭曲线恰好相交于两点,且不会与任两条曲线交于同一点,故平面上一共增加2(n-1)个区域,加上已有的an-1个区域,一共有an-1+2(n-1)个区域。所以本题的递推关系是an=an-1+2(n-1),边界条件是a1=2。