斐波那契数列 学习笔记

   先熟悉一下斐波那契数列

   比如下边这个数列

   0,1,1,2,3,5,8,13,21...

在递归上这个方法定义为 F(0)=0;F(1)=1;F(n)=F(n-1)+F(n-2);


接下来我们推一下斐波那契数列的通项公式(待定系数法)

    设常数r,s使得

 F(n)-rF(n-1)=s*[F(n-1)-r*(F(n-2))]  这个公式为一下推导的关键


移项合并可得

        r+s=1 -rs=1

在n>=3时,有

        F(n)-r*F(n-1)=s*[F(n-1)-r*F(n-2)]

        F(n-1)-r*F(n-2)=s*[F(n-2)-r*F(n-3)]

        ......

        F(3)-r*F(2)=s*[F(2)-r*F(1)]

由上面的式子可得    F(n)-r*F(n-1)=s^(n-2)*[F(2)-r*F(1)];

则由上面公式可以求得F(n)=(s^n-r^n)/(s-r)


由r+s=1 -rs=1

    得 s=(1+sqrt(5))/2   s=(1-sqrt(5))/2

则F(n)=sqrt(5)/5[s^n-r^n]

下面给出一个例题加以分析


题目描述

考虑以下定义在非负整数n上的递归关系: 




其中a、b是满足以下两个条件的常数: 




给定f0, f1, a, b和 n,请你写一个程序计算F(n),可以假定F(n)是绝对值不超过109的整数(四舍五入)。

输入

输入文件一行依次给出5个数,f0 ,f1,a,b和n,f0,f1是绝对值不超过109 ,n是非负整数,不超过109。另外,a、b是满足上述条件的实数,且|a|,|b|≤106 。

输出

一行,F(n)的值

样例输入

0 1 1 1 20

样例输出

6765


  根据上边笔者给出的公式推论  可以得到这个题中的公式推论

            F(n)=k^n*(f(1)-m*f(0))-m^n(f(1)-k*f(0))/(k-m)

其中m=(a+sqrt(a^2+4b))/2,k=(a-sqrt(a^2+4b))/2

附上实现代码(在下边代码中笔者使用的是递归求幂次   读者也可使用快速幂来求解)

#include<iostream>
#include<math.h>
#include<cstdio>
using namespace std;

int n;
double f0,f1,a,b,m,k,ans;

/*在c/c++中,为了解决一些频繁调用的小函数大量消耗栈空间(栈内存)的问题,特别的引入了inline修饰符,表示为内联函数。
栈空间就是指放置程序的局部数据(也就是函数内数据)的内存空间。*/
inline double s(double a,int b)
{
	if(b == 0)
		return 1;
	double  k = s(a , b/2);
	if(b % 2 == 0)
		return k * k;
	else 
		return k * k * a;
}

int main()
{
	cin>>f0>>f1>>a>>b>>n;
	if(f0 == 0 && f1 == 0)
	{
		printf("0");
		return 0;
	}
	m = (a+sqrt(a*a+4*b))/2;
	k = (a-sqrt(a*a+4*b))/2;
	ans = (s(k,n)*(f1-m*f0)-s(m,n)*(f1-k*f0))/(k-m);
	printf("%.0lf\n",ans);
	return 0;
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吃货智

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值