斐波那契数列的矩阵求法,效率O(lgn)

题目
这里写图片描述

按照上述思路,写出下边代码,可以正常运行。

#include "stdafx.h"
#include <iostream>
using namespace std;

void matix_power(int a[][2]);
void matrix_multiply(int a[][2]);
void Fibonacci(int a[][2], int ExpN);


//求Fibonacci的入口
int getFibonacci(int n)
{
    if (n < 0)
    {
        cout << "invalid input" << endl;
        exit(1);
    }

    int a[2][2] ;
    Fibonacci(a,n+1);
    return a[1][1];
}


int main(int argc, _TCHAR* argv[])
{
    cout<<getFibonacci(9)<<endl;
    return 0;
}


/*****************************************************************
* 函数名称:Fibonacci
* 函数功能: 递归调用
*
*参数:
*       a[][2]  //二维数组的指针
*        ExpN    //幂次
*举例:
*       求n=9的斐波那契数。若[1,1;1,0]矩阵的10次方记为矩阵A,则a[1][1]就是所求。
*         --》 10=5*2,先要求出5次方,再平方。
*         --》  5=2*2+1,先要求出2次方,再平方后乘以{1,1;1,0}矩阵
*         --》   2次方已求出
*****************************************************************/
void Fibonacci(int a[][2], int ExpN)
{
    if (ExpN == 1)//1次方
    {
        a[0][0] = 1;
        a[0][1] = 1;
        a[1][0] = 1;
        a[1][1] = 0;
        return;
    }
    if (ExpN == 2)//2次方
    {
        a[0][0] = 2;
        a[0][1] = 1;
        a[1][0] = 1;
        a[1][1] = 1;
        return;
    }
    if (ExpN == 3)//3次方
    {
        a[0][0] = 3;
        a[0][1] = 2;
        a[1][0] = 2;
        a[1][1] = 1;
        return;
    }

    int RootN = (int)(ExpN/2);
    int RemainN = ExpN - RootN*2;
    Fibonacci(a, RootN);
    if (ExpN >= 4)
        matix_power(a);
    if (RemainN==1)
        matrix_multiply(a);

}

/*****************************************************************
* 函数名称: matix_power
* 函数功能:  求矩阵的平方
* 参数:      a[][2]  //矩阵(二维数组)的指针
*****************************************************************/

void matix_power(int a[][2])
{
    int b[2][2];

    b[0][0] = a[0][0] * a[0][0] + a[0][1] * a[1][0];
    b[0][1] = a[0][0] * a[0][1] + a[0][1] * a[1][1];
    b[1][0] = a[1][0] * a[0][0] + a[1][1] * a[1][0];
    b[1][1] = a[1][0] * a[0][1] + a[1][1] * a[1][1];

    a[0][0] = b[0][0];
    a[0][1] = b[0][1];
    a[1][0] = b[1][0];
    a[1][1] = b[1][1];

}

/*****************************************************************
* 函数名称:matrix_multiply
* 函数功能:求{1,1;
*               1,0}矩阵的指定次幂
*参数:
*       a[][2]  //二维数组的指针
*****************************************************************/
void matrix_multiply(int a[][2])
{
    int b[2][2];

    //与[1,1;1,0]矩阵相乘
    b[0][0] = a[0][0] * 1 + a[0][1] * 1;
    b[0][1] = a[0][0] * 1 + a[0][1] * 0;
    b[1][0] = a[1][0] * 1 + a[1][1] * 1;
    b[1][1] = a[1][0] * 1 + a[1][1] * 0;

    a[0][0] = b[0][0];
    a[0][1] = b[0][1];
    a[1][0] = b[1][0];
    a[1][1] = b[1][1];

}

(注:本文的方法就是下边所说的第三种)
这里写图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值