029斐波那契數列的矩陣解法(keep it up)

劍指offer中題目:http://ac.jobdu.com/problem.php?pid=1387

題目描述:

大家都知道斐波那契數列,現在要求輸入一個整數n,請你輸出斐波那契數列的第n項。斐波那契數列的定義如下:

輸入:

輸入可能包含多個測試樣例,對於每個測試案例,

輸入包括一個整數n(1<=n<=70)。

輸出:

對應每個測試案例,

輸出第n項斐波那契數列的值。

樣例輸入:
3
樣例輸出:
2
這個題的一個簡單解法可以for語句來完成:

#include <stdio.h>
 
typedef unsigned long long LLD;
 
LLD fibonacci(LLD vN)
{
    if (vN == 0) return 0;
    if (vN == 1) return 1;
 
    LLD i;
    LLD Fa  = 0;
    LLD Fb  = 1;
    LLD Ret = 0;
 
    for (i = 1; i < vN; ++i)
    {
        Ret = Fb + Fa;
        Fa  = Fb;
        Fb  = Ret;
    }
 
    return Ret;
}
 
int main()
{
    LLD N;
 
    while (scanf("%lld", &N) != EOF)
    {
        printf("%lld\n", fibonacci(N));
    }
 
    return 0;
}
/**************************************************************
    Problem: 1387
    User: 
    Language: C
    Result: Accepted
    Time:0 ms
    Memory:912 kb
****************************************************************/

下面來說一下用矩陣的方法來解:

f(2) = 1* f(1) + 1*f(0);

f(1) = 1*f(1) +  0*f(0);

那麼f(3) 和 f(2)呢

f(3) = 1*f(2) + 1*f(1);

f(2) = 1*f(2) + 0*f(1);

細心的你已經能發現規律了:

f(n)               1       1           f(n-1)

             =                                  

f(n-1)            1        0         f(n-2)

初始f(1) = 1, f(0) = 0;

代碼:

#include <stdio.h>
 
typedef unsigned long long ULLD;
 
typedef struct SMatrix4
{
    ULLD 
        m00, m01,
        m10, m11
        ;
}SMatrix4;
 
SMatrix4 multyMatrix(const SMatrix4 *vLeft, const SMatrix4 *vRight)
{
    SMatrix4 Ret;
    Ret.m00 = vLeft->m00 * vRight->m00 + vLeft->m01 * vRight->m10;
    Ret.m01 = vLeft->m00 * vRight->m01 + vLeft->m01 * vRight->m11;
    Ret.m10 = vLeft->m10 * vRight->m00 + vLeft->m11 * vRight->m10;
    Ret.m11 = vLeft->m10 * vRight->m01 + vLeft->m11 * vRight->m11;
    return Ret;
}
 
ULLD getFibN(ULLD vN)
{
    if (vN == 0) return 0;
    if (vN == 1) return 1;
 
    ULLD F0 = 0;
    ULLD F1 = 1;
    ULLD N  = vN - 1;
    ULLD R0 = 1;
    ULLD R1 = 0;
 
    SMatrix4 MatX;
    MatX.m00 = 1;
    MatX.m01 = 1;
    MatX.m10 = 1;
    MatX.m11 = 0;
 
    while (N)
    {
        if (N%2)
        {
            ULLD TempR0 = MatX.m00 * R0 + MatX.m01 * R1;
            ULLD TempR1 = MatX.m10 * R0 + MatX.m11 * R1;
            R0 = TempR0;
            R1 = TempR1;
            --N;
        }
        else
        {
            MatX = multyMatrix(&MatX, &MatX);
            N = N>>1;
        }
    }
 
    return R0;
}
 
int main()
{
    ULLD N;
 
    while (scanf("%lld", &N) != EOF)
    {
        printf("%lld\n", getFibN(N));
    }
 
    return 0;
}
/**************************************************************
    Problem: 1387
    User: 
    Language: C
    Result: Accepted
    Time:0 ms
    Memory:912 kb
****************************************************************/








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