您的位置:首页 > 编程语言 > C语言/C++

029斐波那契数列的矩阵解法(keep it up)

2014-11-09 22:05 447 查看
剑指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
****************************************************************/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  C++ algorithm