1.题目描述:
写一个函数,输入n,求斐波那(Fibonacci)数列的第n项。斐波那契数列的定义如下:
2.源代码:
// Copyright (c) 2015年 skewrain. All rights reserved.
#include <iostream>
#include <stdio.h>
using namespace std;
//递归,效率很低的解法,时间复杂度是以n的指数的方式递增的。
long long Fibonacci1(unsigned int n)
{
if(n <= 0)
return 0;
if(n == 1)
return 1;
return Fibonacci1(n-1) + Fibonacci1(n-2);
}
//简单的迭代方法,从下往上计算,时间复杂度为O(n)。
long long Fibonacci2(unsigned int n)
{
int result[2] = {0,1};
if(n<2)
return result[n];
long long fibNMinusOne = 1;
long long fibNMinusTwo = 0;
long long fibN = 0;
for(unsigned int i = 2;i <= n; ++i)
{
fibN = fibNMinusOne + fibNMinusTwo;
fibNMinusTwo = fibNMinusOne;
fibNMinusOne = fibN;
}
return fibN;
}
int main(int argc,char *argv[]){
int n1,n2;
cout<<"请输入n1:";
cin>>n1;
cout<<"F("<<n1<<")的值为:"<<Fibonacci1(n1)<<endl;
cout<<"请输入n2:";
cin>>n2;
cout<<"F("<<n2<<")的值为:"<<Fibonacci2(n2)<<endl;
return 0;
}
A.【青蛙跳台阶】一只青蛙一次可以跳上1级台阶,也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
分析:
1)首先我们考虑最简单的情况。如果只有1级台阶,那显然只有一种跳法。如果有2级台阶,那就有两种跳得方法了:一种是分两次跳,每次跳1级;另外一种就是一次跳2级。
2)接着我们再来讨论一般情况。如果把n级台阶时的跳法看成是n的函数,记为f(n)。当n>2时,第一次跳的时候就有两种不同的选择:一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1);另外一种选择是第一次跳2级,此时跳法数目等于后面剩下的n-2级台阶的跳法数目,即为f(n-2)。因此n级台阶的不同跳法的总数f(n)=f(n-1)+f(n-2)。我们可以看出是斐波那契数列了。
源代码:
long long jumpFloorI(int number)
{
if(number<=1)
return 1;
if(number==2)
return 2;
long long result[100];
result[1] = 1;
result[2] = 2;
for (int i = 3; i<number+1; i++) {
result[i] = result[i-1]+result[i-2];
}
return result[number];
}
B.【疯狂跳台阶】一只青蛙一次可以跳上1级台阶,也可以跳上2级......它也可以跳上n级。求该青蛙跳上一个n级的台阶总共有多少种跳法。
分析:
假设现在n=10,方法记为f(10),如果第一下跳了1级,那么剩下的方法为f(9),如果第一下跳了2级,那么剩下的方法是f(8),……,如果第一下跳了9级,那么剩下的方法是f(1),如果第一下就直接跳上10级,那么就只有一种方法。
因此,f(10)=f(9)+f(8)+f(7)+f(6)+f(5)+f(4)+f(3)+f(2)+f(1)+1;
刚开始f(1)=1,f(2)=2。
源代码:
long long jumpFloorII(int number)
{
if(number<=1)
return 1;
if(number==2)
return 2;
long long result[100];
result[1] = 1;
result[2] = 3;
for (int i = 3; i<=number; i++)
{
{
for(int j = 1;j<i;j++)
result[i] += result[j];
}
result[i] += 1;
}
return result[number];
}