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项斐波那契数列的值。
样例输入:
样例输出:
这个题的一个简单解法可以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
****************************************************************/
题目描述:
大家都知道斐波那契数列,现在要求输入一个整数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
****************************************************************/
相关文章推荐
- 006矩阵旋转90度(keep it up)
- (017)将一棵二叉查找树重构成链表(keep it up)
- 035树的子结构(keep it up)
- 014敲代码将一个栈按升序排序,对这个栈是怎样实现的,你不应该做不论什么特殊的如果(keep it up)
- 027根据前序遍历和中序遍历,重建二叉树(keep it up)
- 034链表中倒数第k个结点(keep it up)
- 004串重量 (keep it up)
- 014写程序将一个栈按升序排序,对这个栈是如何实现的,你不应该做任何特殊的假设(keep it up)
- 《剑指offer》面试题10:斐波那契数列(含矩阵乘法解法)
- 028用两个栈实现队列(keep it up)
- 031 二进制1的数量(keep it up, 看到这个问题,刚开始有点蒙)
- 007 字符串(keep it up)
- 032数值的整数次方(keep it up)
- 021位操作1(keep it up)
- 024二维数组中的查找(keep it up)
- 036二叉树的镜像(keep it up)
- How to sync a fork repo to keep it up-to-date with the upstream repo on Windows?
- 025 替换字符串中的空格(keep it up)
- 031 二进制中1的个数(keep it up, 看到这个题刚开始有点蒙)
- 008实现一个算法从一个单链表中返回倒数第n个元素(keep it up)