第 19 题(数组、递归):
题目:定义 Fibonacci 数列如下:
/ 0 n=0
f(n)= 1 n=1
/ f(n-1)+f(n-2) n=2
输入 n,用最快的方法求该数列的第 n 项。

思路:递归和非递归的 下面的代码有个问题,没有考虑大数越界。返回值应该设成long long型的

递归速度非常慢

/*
第 19 题(数组、递归):
题目:定义 Fibonacci 数列如下:
/ 0 n=0
f(n)= 1 n=1
/ f(n-1)+f(n-2) n=2
输入 n,用最快的方法求该数列的第 n 项。
start time 13:05
end time 13:16
*/ #include <stdio.h> //递归
int Fibonacci(int n)
{
switch(n)
{
case :
return ;
case :
return ;
default:
return Fibonacci(n - ) + Fibonacci(n - );
}
} //非递归
int nonrecursionFibonacci(int n)
{
int a = , b = ;
switch(n)
{
case :
return ;
case :
return ;
default:
{
for (int i = ; i < n - ; i++)
{
int c = a + b;
a = b;
b = c;
}
return b;
}
}
} int main()
{
//int f = Fibonacci(10000);
int ff = nonrecursionFibonacci();
return ;
}

网上有O(logN)的解法

http://leowzy.iteye.com/blog/787947

这还不是最快的方法。下面介绍一种时间复杂度是O(logn)的方法。在介绍这种方法之前,先介绍一个数学公式:
{f(n), f(n-1), f(n-1),
f(n-2)} ={1, 1, 1,0}n-1
(注:{f(n+1), f(n), f(n),
f(n-1)}表示一个矩阵。在矩阵中第一行第一列是f(n+1),第一行第二列是f(n),第二行第一列是f(n),第二行第二列是f(n-1)。)

有了这个公式,要求得f(n),我们只需要求得矩阵{1, 1, 1,0}的n-1次方,因为矩阵{1, 1,
1,0}的n-1次方的结果的第一行第一列就是f(n)。这个数学公式用数学归纳法不难证明。感兴趣的朋友不妨自己证明一下。
现在的问题转换为求矩阵{1,
1, 1, 0}的乘方。如果简单第从0开始循环,n次方将需要n次运算,并不比前面的方法要快。但我们可以考虑乘方的如下性质:
         /  
an/2*an/2                       n为偶数时
an=
         \  
a(n-1)/2*a(n-1)/2             n为奇数时

要求得n次方,我们先求得n/2次方,再把n/2的结果平方一下。如果把求n次方的问题看成一个大问题,把求n/2看成一个较小的问题。这种把大问题分解成一个或多个小问题的思路我们称之为分治法。这样求n次方就只需要logn次运算了。

实现这种方式时,首先需要定义一个2×2的矩阵,并且定义好矩阵的乘法以及乘方运算。当这些运算定义好了之后,剩下的事情就变得非常简单。完整的实现代码如下所示。

#include <cassert>
///////////////////////////////////////////////////////////////////////
// A 2 by 2 matrix
///////////////////////////////////////////////////////////////////////
struct Matrix2By2
{
Matrix2By2
(
long long m00 = ,
long long m01 = ,
long long m10 = ,
long long m11 =
)
:m_00(m00), m_01(m01), m_10(m10), m_11(m11)
{
} long long m_00;
long long m_01;
long long m_10;
long long m_11;
}; ///////////////////////////////////////////////////////////////////////
// Multiply two matrices
// Input: matrix1 - the first matrix
// matrix2 - the second matrix
//Output: the production of two matrices
///////////////////////////////////////////////////////////////////////
Matrix2By2 MatrixMultiply
(
const Matrix2By2& matrix1,
const Matrix2By2& matrix2
)
{
return Matrix2By2(
matrix1.m_00 * matrix2.m_00 + matrix1.m_01 * matrix2.m_10,
matrix1.m_00 * matrix2.m_01 + matrix1.m_01 * matrix2.m_11,
matrix1.m_10 * matrix2.m_00 + matrix1.m_11 * matrix2.m_10,
matrix1.m_10 * matrix2.m_01 + matrix1.m_11 * matrix2.m_11);
} ///////////////////////////////////////////////////////////////////////
// The nth power of matrix
// 1 1
// 1 0
///////////////////////////////////////////////////////////////////////
Matrix2By2 MatrixPower(unsigned int n)
{
assert(n > ); Matrix2By2 matrix;
if(n == )
{
matrix = Matrix2By2(, , , );
}
else if(n % == )
{
matrix = MatrixPower(n / );
matrix = MatrixMultiply(matrix, matrix);
}
else if(n % == )
{
matrix = MatrixPower((n - ) / );
matrix = MatrixMultiply(matrix, matrix);
matrix = MatrixMultiply(matrix, Matrix2By2(, , , ));
} return matrix;
} ///////////////////////////////////////////////////////////////////////
// Calculate the nth item of Fibonacci Series using devide and conquer
///////////////////////////////////////////////////////////////////////
long long Fibonacci_Solution3(unsigned int n)
{
int result[] = {, };
if(n < )
return result[n]; Matrix2By2 PowerNMinus2 = MatrixPower(n - );
return PowerNMinus2.m_00;
}

【编程题目】题目:定义 Fibonacci 数列 输入 n,用最快的方法求该数列的第 n 项。的更多相关文章

  1. Interview----用最快的方法计算 Fibonacci 数

    输入 n, 用最快的方法求该 Fibocacci 数列的第 n 项. 方法1: 递归,非常慢 方法2: 迭代,因此计算 f[1] , f[2], f[3] ,,,, 复杂度 O(N) 方法3: 采用以 ...

  2. 输入两个整数n 和m,从数列1,2,3.......n 中任意取几个数, 使其和等于m ,要求将当中全部的可能组合列出来

    中兴面试题之中的一个.难度系数中. 题目描写叙述例如以下:输入两个整数n 和m,从数列1,2.3.......n 中任意取几个数, 使其和等于m ,要求将当中全部的可能组合列出来. 逻辑分析: 1.比 ...

  3. Fibonacci数列对任何数取模都是一个周期数列

    题目是要求出斐波那契数列n项对一个正整数取模,那么可以把斐波那契数列取模后得到的数列周期求出来. 比如下面一个题目:求出f[n]的后4位,先求出数列对10000取模的周期,然后再查找即可. #incl ...

  4. 【Visual C++】游戏编程学习笔记之八:鼠标输入消息(小demo)

     本系列文章由@二货梦想家张程 所写,转载请注明出处. 作者:ZeeCoder  微博链接:http://weibo.com/zc463717263 我的邮箱:michealfloyd@126.c ...

  5. 面试题:输入两个整数 n 和 m,从数列1,2,3…….n 中 随意取几个数, 使其和等于 m

    问题: 2010年中兴面试题 编程求解: 输入两个整数 n 和 m,从数列1,2,3…….n 中 随意取几个数, 使其和等于 m ,要求将其中所有的可能组合列出来. 思路: 类似这种组合问题一般都是使 ...

  6. 整数数组的定义,然后输入一个整数X,假定X不在这个数组,返回小于X位置的最大数目i而超过X位置的最小数目j

    //整数数组的定义,然后输入一个整数x,假定X不在这个数组,返回小于X位置的最大数目i而超过X位置的最小数目j: //如果X在该阵列,返回位置的阵列中的数. 资源: #include<iostr ...

  7. Codeforces Round #467 (Div. 2) A. Olympiad[输入一组数,求该数列合法的子集个数]

    A. Olympiad time limit per test 1 second memory limit per test 256 megabytes input standard input ou ...

  8. HDU3977 Evil teacher 求fib数列模p的最小循环节

    In the math class, the evil teacher gave you one unprecedented problem! Here f(n) is the n-th fibona ...

  9. C语言笔试经典--求分数数列的和

    题目: 求数组的和    2   3/2   5/3   8/5  13/8   21/13  ...    求前20项的和 //求分数数列的和 #include<stdio.h> // ...

随机推荐

  1. ansible的使用技巧

    #查看ansible的帮助 $ ansible -h   #ansible 指定不通的模块执行 $ ansible -i /etc/ansible/hosts  docker -u root -m c ...

  2. 数论只会GCD。。。

    一些关于GCD的代码.... #include <iostream> #include <cstdio> #include <cstring> using name ...

  3. 【python网络编程】使用rsa加密算法模块模拟登录新浪微博

    一.基础知识 http://blog.csdn.net/pi9nc/article/details/9734437 二.模拟登录 因为上学期参加了一个大数据比赛,需要抓取数据,所以就想着写个爬虫抓取新 ...

  4. java之远程接口调用

    一.通过地址栏传值 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi ...

  5. MongoDB—— 读操作 Core MongoDB Operations (CRUD)

    本文主要介绍内容:从MongoDB中请求数据的不同的方法 Note:All of the examples in this document use the mongo shell interface ...

  6. word20161205

    cluster-aware application / 支持群集的应用程序 cluster-unaware application / 不支持群集的应用程序 Cluster.exe CNAME (ca ...

  7. PYTHON 文件操作

    对文件操作流程 打开文件,得到文件句柄并赋值给一个变量 通过句柄对文件进行操作 关闭文件 现有文件如下 Beautiful is better than ugly. 优美胜于丑陋 Explicit i ...

  8. linux kernel 杂谈

    首先介绍一下背景吧,工作三个星期了.复习了一波u-boot,跟了一下事件上报,搞了下平台设备,扣了一个内存检查代码. 想想生活是不是有点无聊.对啊,真的很无聊!!!! 无聊也没有办法啊,所以找点方法去 ...

  9. net-snmp源码VS2013编译添加加密支持(OpenSSL)

    net-snmp源码VS2013编译添加加密支持(OpenSSL) snmp v3 协议使用了基于用户的安全模型,具有认证和加密两个模块. 认证使用的算法是一般的消息摘要算法,例如MD5/SHA等.这 ...

  10. hdu1520 树形dp Anniversary party

    A - Anniversary party Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I6 ...