递推的简单入门
第一篇博文的观看量日益增加,我感到很开心。能把我所学到的东西分享给大家,并得到大家的认可,是我一直写下去的动力,愿你我能共同进步,加油!!!
递推法的基本思想
递推就是利用问题本身所具有的一种递推关系来求解问题的一种方法,是指从已知的初始条件出发,依据某种递推关系,逐次推出所要计算的中间结果和最终结果。
对于初始条件:
1.要么在问题的本身已经给定
2.要么通过对问题的分析化简后来确定。
递推的本质
把一个复杂的计算过程转化为一个简单的过程的多次计算。可递推求解的问题特点
1 问题可以划分成多个状态。
2 除了初始状态外,其他各状态都可以用固定的关系式来求解。递推的应用
1 常用于按照一定的规律来计算序列中的指定项。
2 递推关系式不会直接给出。(通过分析问题的状态,再使用归纳法来找出递推的关系式)递推的方法
1,正向顺推:从已知的条件出发,向着所求问题前进,最终与所求的问题联立。
2,反向逆推:从所求的问题出发,向着已知条件靠拢,最后与已知条件联系起来。(从所求的问题出发一步步还原出答案)
下面我通过一些问题的讲解来带领大家进一步感受递推
- 养兔子问题
Description
一对成熟的兔子每天能且只能产下一对小兔子,每次都生一公一母,每只小兔子的成熟期是1天,小兔子出生后隔一天才能再生小兔子。第一天某人领养了一对成熟的兔子,一公一母,请问第N天以后,他将会得到多少对兔子。
Input
输入为一个整数n(1 ≤ n ≤ 90)。
Output
对应输出第n天有几对兔子(假设没有兔子死亡现象,而且是一夫一妻制)。
Sample
Input
2
Output
2
Hint
数据类型可以用64位整数:long long
通过对问题的分析,我们可以得到:
首先,我们分析一下问题的状态,第n天的兔子肯定由已经成熟的兔子,和刚出生的兔子组成,可以把这看成两种状态。接下来,我们通过已经找到的状态来找问题的递推关系,(总的来说,我们要求某一天的兔子个数,要依靠前几天的兔子个数来判定(反向逆推),现在我们假设第n天的兔子个数我们都已知,这样我们就可以放心的求解问题了 )
第一步,求第n天的成兔个数,根据我们对题意的理解我们可以得到,第n-1天的兔子到第n天都可以变成成兔(不考虑兔子再生的情况,因为刚生下来的兔子都是小兔),就可以当作是一种继承。
第二步,求第n天的小兔个数,我们发现通过第n-1 天的兔子数求不方便(因为,我们知到小兔都是由成兔产下的,第n-1天的小兔在第n天不能产下小兔,我们也不知道第n-1天的小兔数量),由小兔隔一天可以生下小兔,我们可以联想到用第n-2天的兔子来求解,事实证明也是对的,因为第n-2 天的小兔在第n天时都可以产下小兔,所以第n天的小兔的数量就是前两天兔子的数量。
这样我们就可以列出递推关系式,设第n天的兔子数量为f[n] ,
f[n]=f[n-1]+f[n-2];
这恰好是斐波那契数列。下面给出代码。
#include <iostream>
using namespace std;
const int M=1e3+10;
int main()
{
int n;
long long int f[M];
cin>>n;
f[1]=1;
f[2]=2;
for(int i=3;i<=n;i++)
{
f[i]=f[i-1]+f[i-2];
}
cout<<f[n];
return 0;
}
ps:有些人可能还有一些疑问:为什么第n-1天的成兔生下的小兔会不会对结果产生影响呢?
当时我想了比较长的时间,可能是我比较笨吧
原因:想想第n-1天的成兔来源,不正是由第n-2天的成兔的继承和小兔的生长而来的吗,也就是第n-2天所有的兔子数量。(其实是反复运用了第一步)
- 骨牌铺方格问题
Description
在2×n的一个长方形方格中,用一个1× 2的骨牌铺满方格,输入n ,输出铺放方案的总数. 例如n=3时,为2× 3方格,骨牌的铺放方案有三种,如下图:
Input
输入包含一个整数n,表示该测试实例的长方形方格的规格是2×n (0< n<=50)。
Output
输出铺放方案的总数。
Sample
Input
3
Output
3
这个问题呢我相信会有人乍一看非常懵,没错正是本人 ,由于这个题的方法有点抽象,对于初次接触到的新人来说呢,理解起来会有点别扭,我就稍微点一下思路,随着以后大家对于递推的理解进一步加深,再来看这一道题目就非常的容易。
还是使用反向逆推的方法:
我们可以看到最后面只有两种情况,竖着排一个和横着排两个,继续往前推还是这两种情况&