1、题目描述
有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子.假如兔子都不死,并且第一个月出生一对兔子,请问第n个月有多少只兔子?
分析
第一个月:1对
第二个月:1 对
第三个月:1对+新生=2对
第四个月:已有的兔子+新生=2+1=3对
第五个月=已有的兔子+新生=3+2=5
第n个月:f(n)=f(n-1)+f(n-2)
2、斐波那契数列
1)、递推
f(n)=f(n-1)+f(n-2)
#include<iostream>
using namepace std;
int f[200000];
int main(){
int n;
cin>>n;
f[1]=f[2]=1;
for (int i=3;i<=n;i++){
f[i]=f[i-1]+f[i-2];
}
cout<<f[n]<<endl;
return 0;}
2)、滚动数组优化
#include<iostream>
using namepace std;
int f[3];
int main(){
int n;
cin>>n;
f[1]=f[2]=1;
for (int i=3;i<=n;i++){
f[i%3]=f[(i-1)%3]+f[(i-2)%3];
}
cout<<f[n%3]<<endl;
return 0;}
3)、三个变量
#include<iostream>
using namepace std
int main(){
int n;
cin>>n;
int a, b,c;
c=a=b=1;
for (int i=3;i<=n;i++){
c=b+a;
a=b;
b=c;
}
cout<<c<<endl;
return 0;}
4)、递归解法
#include<iostream>
using namepace std;
int find(int n)
{
if(n==1 || n==2) return 1;
else
{
return find(n-1)+find(n-2);
int main(){
int n;
cin>>n;
cout<<find(n)<<endl;
return 0;}
5)记忆化递归
#include<iostream>
#include<cstring>
using namepace std;
int cache[200000];
int find(int n)
// r如果缓存中存在,就直接缓存,否则计算,然后将计算的结果保存到缓存;
{
if(cache[n]!=-1) return cache[n];
else
{
return cache[n]=find(n-1)+find(n-2);
int main(){
int n;
cin>>n;
memset(cache,-1,sizeof(cache));
cache[2]=cache[1]=1
cout<<find(n)<<endl;
return 0;}
总结:递归和递推的关系
递推主要指通过找规律找到递推表达式,是一种解决问题的方式
递归是指递归该函数,指递归函数自己调用自己的函数,是一种编程方式
6)矩阵快速幂
#include<iostream>
#include<cstring>
using namespace std;
//定义矩阵对应的结构体
struct Matrix{
int row,column;
Matrix(){
memset(v,0,sizeof(v));
}
};
Matrix multiply(Matrix a,Matrix b){
Matrix ans;
ans.row=a.row;
ans.column=b.column;
for(int i=1;i<=a.row;i++)
{
for(int j=1;j<=b.column;j++)
for(int k=1;k<=a.column;k++)
{
ans.v[i][j]+=a.[i][k]*b.v[k][j];
}
}
return ans;
}
Matrix power(Matrix a, long long n){
Matrix ans;
ans.v[1][1]=ans.v[2][2]=1;
while(){
if(n%2 ==1) ans=multiply(ans,base);
bse=multiply(base,base);
n/=2;
}
return ans;
}
int main(){
long long n;
cin>>n;
Matrix ans, base ,last;
base.row=2;
base.column=2;
base.v[1][1]=base.v[1][2]=base.v[2][1]=1;
last.row=2;
last.colun=1;
last.v[1][1]=last.v[2][1]=1;
if(n==1 ||n==2)
cout<<1<<endl;
else{
ans=pow(base,n-2);
ans=multiply(ans,last);
cout<<ans.v[1][1]<<endl;}
return 0;}