算法编程:计算斐波那契数列

实现代码:C++

实现方法:通过递推法、递归法、矩阵快速幂方法

适用:

范围小且单次查询时,可以不用记忆化处理。

范围大或多次查询时,应使用记忆化处理。

时间复杂度:

递归法:O(n^2)-->递推法(动态规划):O(n)-->矩阵快速幂:O(nlgn)-->斐波那契数列公式:O(1)

目录

递推法:

递推法+记忆化:

递归法:

递归法+记忆化:

矩阵快速幂方法:

 斐波那契通项公式:

递推法:

#include<bits/stdc++.h>
using namespace std;
int main()
{
	int n;
	int x = 0;
	int y = 1;
	int ans;
	
	cin >> n;
	if(n == 0)ans = 0;
	
	else if(n = 1)ans = 1;
	else {
		for(int i = 2;i <= n;++ i)
		{
			ans = x + y;
			x = y;
			y = ans;
		}
	}
	
	cout << ans << endl;
	return 0;
}

递推法+记忆化:

#include<bits/stdc++.h>
using namespace std;
vector<int>f;


int main()
{
	int n;
	cin >> n;
	f.push_back(0);
	f.push_back(1);
	for(int i = 2;i <= n;++ i)
	{
		f.push_back(f[i-1]+f[i-2]);
	}
	for(int i = 1;i <= n;++ i)
	{
		cout << f[i] << endl;
	}
	return 0;
}

递归法:


  #include <iostream>
  using namespace std;
  
	  int fn(int n)
  {
	  //递归出口1
	  if(n==0)
	  return 0;
  
  //递归出口2
	  else if(n==1 )
	  return 1;
  
	  else
	  return fn(n-1)+fn(n-2); 
  }
  
  
  int main()
  {
	  
	  int n; 
	  int ans;
  
	  cin>>n;
  
	  ans=fn(n);
  
	  cout<<ans<<endl;
  }

递归法+记忆化:

#include<bits/stdc++.h>
using namespace std;
using ll = long long;
const ll p = 1e9 + 7;
const int inf = 1e9,N = 1e5 + 3;
ll dp[N];

ll f(int n)
{
	if(n <= 2)return 1;
	if(dp[n] != -1)return dp[n];
	
	return dp[n] = (f(n - 1) + f(n - 2)) % p;
}


int main()
{
	memset(dp,-1,sizeof dp);
	int n;cin >> n;
	cout << f(n) << endl;
	
	return 0;
}

矩阵快速幂方法:

//计算斐波那契数列有很多种方法,而当阶数N很大时,矩阵快速幂算法是最佳的 
#include <bits/stdc++.h>

using namespace std;

typedef unsigned long long ull;

const int mod=1e9+7;

class Matrix//矩阵类 
{
public:
	int row,col;//row为矩阵的行数,col为矩阵的列数 
	ull matrix[5][5];//矩阵 
	Matrix(int r=2,int c=2,int tag=0)//构造函数 
	{
		row=r;
		col=c;
		memset(matrix,0,sizeof(matrix));
		if(tag)//若传入tag为非0,则初始化为单位矩阵 
		{
			for(int i=0;i<min(r,c);i++)
			{
				matrix[i][i]=1;//对角线元素初始化为1 
			}    
		}    
	}        
};

Matrix operator *(Matrix m1,Matrix m2)//矩阵乘法,返回结果矩阵 
{
	Matrix ans;//构造一个2行2列的矩阵,初始化均为0 
	memset(ans.matrix,0,sizeof(ans.matrix));
	for(int i=0;i<m1.row;i++)//遍历第一个矩阵的每一行 
	{
		for(int j=0;j<m2.col;j++)//遍历第二个矩阵的每一列 
		{
			for(int k=0;k<m1.col;k++)//第一个矩阵的行与第二个矩阵的列一一对应相乘再相加 
			{
				ull tmp=m1.matrix[i][k]*m2.matrix[k][j]%mod; 
				ans.matrix[i][j]=(ans.matrix[i][j]+tmp)%mod;
			}
		}
	}
	return ans;
}

Matrix matrix_mul(Matrix m,ull power)//矩阵快速幂,求解矩阵m的power次幂 
//原理与普通快速幂相同,重载了矩阵相乘的函数之后可直接套用普通快速幂算法 
{
	Matrix ans(2,2,1);//初始化为单位矩阵 
	while(power)
	{    
		if(power&1)
		{
			ans=ans*m;
			power--;
		}
		power=power>>1;
		m=m*m;
	}
	return ans;
}

ull F(Matrix M,ull n)//计算N阶斐波那契数列 
{
	Matrix ans=matrix_mul(M,n);//计算矩阵M的N次幂 
	return ans.matrix[1][0];//取其右下角元素即为最终答案 
}

int main()
{
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int T;
	cin>>T;
	Matrix M(2,2,0);
	//构造一个矩阵为{ {1,1} , {1,0} } 
	//N阶斐波那契数列等于该矩阵的N次幂的右上角/左下角元素 
	M.matrix[0][0]=M.matrix[0][1]=1;
	M.matrix[1][0]=1;
	M.matrix[1][1]=0;
	while(T--)
	{
		ull N;
		cin>>N;
		cout<<F(M,N)<<endl;
	}
	return 0;
}

 斐波那契通项公式:

  • 9
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值