斐波那契數列的矩陣求法,效率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];

}

(注:本文的方法就是下邊所說的第三種)
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章