斐波那契效率问题和矩阵快速幂

暴力递归

int f(int n){
	return (n<=2) ? 1 : f(n-1)+f(n-2);
}

这样画出递归树会发现同一个n值,f(n)被算了很多遍。比如f(5)的递归树:
在这里插入图片描述
越底层重复算的次数越多,时间用这个树的节点个数来算,就是指数级别的可怕结果。

记忆化搜索

可以开个数组把算过的记下来,再算就直接用不用往下递归。

int f(int n){
	return F[n] ? F[n] : (F[n]=f(n-1)+f(n-2));
}

上面的树会变成
在这里插入图片描述
第二次f(3)的子树没了,记忆化搜索是动态规划的雏形。

数组递推

for(int i=1;i<=n;i++){
	F[n]=F[n-1]+F[n-2];
}

直接f[n]=f[n-1]+f[n-2]。O(n)循环一遍。

滚动递推

Fn_1=1,Fn_2=1;
for(int i=3;i<=n;i++){
	Fn=Fn_1+Fn_2;
	Fn_2=Fn_1;
	Fn_1=Fn;
}

我们发现n只和n-1和n-2有关,所以只要滚动维护当前的三个数就行。

矩阵快速幂

[ f ( n ) f ( n − 1 ) ] = [ 1 1 1 0 ] ∗ [ f ( n − 1 ) f ( n − 2 ) ] \begin{bmatrix} f(n)\\f(n-1)\end{bmatrix}=\begin{bmatrix} 1 & 1 \\ 1 & 0 \end{bmatrix}*\begin{bmatrix} f(n-1)\\f(n-2)\end{bmatrix} [f(n)f(n1)]=[1110][f(n1)f(n2)]
根据矩阵的结合律可以用二进制快速幂求解。时间复杂度O(logn)。
完整代码:

#include<cstdio>
using namespace std;
class mtrx22{
public:
	int a[2][2];
	friend mtrx22 operator *(mtrx22,mtrx22);
	mtrx22(int aa,int b,int c,int d){
		a[0][0]=aa,a[0][1]=b,a[1][0]=c,a[1][1]=d;
	}
	void print(){
		printf("%d %d\n",a[0][0],a[0][1]);
		printf("%d %d\n",a[1][0],a[1][1]);
		printf("\n");
	}
};
mtrx22 operator *(mtrx22 x,mtrx22 y){
	mtrx22 neww(0,0,0,0);
	neww.a[0][0]=x.a[0][0]*y.a[0][0]+x.a[0][1]*y.a[1][0];
	neww.a[0][1]=x.a[0][0]*y.a[0][1]+x.a[0][1]*y.a[1][1];
	neww.a[1][0]=x.a[1][0]*y.a[0][0]+x.a[1][1]*y.a[1][0];
	neww.a[1][1]=x.a[1][0]*y.a[0][1]+x.a[1][1]*y.a[1][1];
	return neww;
}
mtrx22 quick_pow(mtrx22 d,int x){
	mtrx22 p=d,res(1,0,0,1);
	while(x){
		if(x%2==1){
			res=p*res;
		}
		x/=2;
		p=p*p;
	}
	return res;
}
int main(){
	int n;scanf("%d",&n);
	mtrx22 loww(1,1,1,0);
	mtrx22 ans=quick_pow(loww,n-2);
	printf("%d\n",ans.a[0][0]+ans.a[0][1]);
	return 0;
}

求特征矩阵带出公式

这个是就出底数矩阵的特征矩阵,然后利用对角阵的优良性质带出通向公式。但是特征值是无理数,所以还要求无理数的高次运算,复杂度还是log的,而且容易产生精度问题。所以还不如用矩阵快速幂做。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值