代码改变世界

多种方式求fibonacci数列

2012-04-14 17:14  youxin  阅读(457)  评论(0)    收藏  举报

方法如下:

/*
f[1]=1;f[2]=1; f[n]=f[n-2]+f[n-1] ;
*/
#include<iostream>
using namespace std;
int fibonacci(int n)
{
    int *f=new int[n+1];//第0个元素不放
    f[1]=1;
    f[2]=1;
    for(int i=3;i<=n;i++)
        f[i]=f[i-2]+f[i-1];
    return f[n];

}

/*递归效率非常之慢 */
int fibonacci2(int n)
{
    
    if(n==1)
        return 1;
    else if(n==2)
        return 1;
    else
        return fibonacci2(n-2)+fibonacci2(n-1);
}
int fibonacci3(int n)
{
    int f_twoback=1;
    int f_oneback=1;
    int f;
    
    if(n==1) return 1;
    if(n==2) return 1;
    for(int i=3;i<=n;i++)
    {
        f=f_twoback+f_oneback;
        f_twoback=f_oneback;
        f_oneback=f;
    }
    return f;
}



int main()
{
    int n;
    cin>>n;
    cout<<fibonacci(n)<<endl;
    cout<<fibonacci2(n)<<endl;
    cout<<fibonacci3(n)<<endl;
    return 0;
}

第一种方法:开辟了一个数组来存储算过的值,时间效率非常高,但浪费了空间。

所以在我看来动态规划的基本思想就是保存递归时的结果,因而不会在解决同样的问题时花费时间 。动态规划通常用于求解最优化问题,他同分治算法类似,都是将待求解的问题分解为若干子问题,先求解子问题然后得出原问题的解。与分治不同之处在于分治算法各个子问题是互相独立的而动态规划类的子问题往往是相互联系的。

同样是求解最优化问题的贪心算法与动态规划的区别在于贪心算法追求每一步都达到最优,而动态规划则是追求整体的最优。

要使用动态规划算法必须满足最优化原理和无后效性。最优化原理就是:一个最优化策略的子策略总是最优的。而无后效性简而言之就是当前的决策与过去的状态无关。

使用动态规划算法的步骤:(1)分析最优解的性质,并刻画其结构特征。(2)递归定义最优值。(3)以自底向上或者自顶向下的记忆方法计算最优值。

动态规划的有一些经典题目:背包问题、矩阵链乘、最长公共子序列……可以拿来做一下,加深自己的印象。

第二种方法;用递归,时间效率非常低。为什么?(没有保存已经计算得出的结果)

n=3 时,f1,f2个计算一次,共2次

n=4时,f2,f3 为计算f3需两个基本运算,因而f2又被计算一次,共3个基本运算

n=5时,f3,f4 ,需5个基本运算

fn>(3/2)^n-1;

递归求解过程如下:

 

第3种:迭代来求

/*
f[1]=1;f[2]=1; f[n]=f[n-2]+f[n-1] ;
*/
#include<iostream>
using namespace std;
int fibonacci(int n)
{
    int *f=new int[n+1];//第0个元素不放
    f[1]=1;
    f[2]=1;
    for(int i=3;i<=n;i++)
        f[i]=f[i-2]+f[i-1];
    return f[n];

}

/*递归效率非常之慢 */
int fibonacci2(int n)
{
    
    if(n==1)
        return 1;
    else if(n==2)
        return 1;
    else
        return fibonacci2(n-2)+fibonacci2(n-1);
}
int fibonacci3(int n)
{
    int f_twoback=1;
    int f_oneback=1;
    int f;
    
    if(n==1) return 1;
    if(n==2) return 1;
    for(int i=3;i<=n;i++)
    {
        f=f_twoback+f_oneback;
        f_twoback=f_oneback;
        f_oneback=f;
    }
    return f;
}



int main()
{
    int n;
    cin>>n;
    //cout<<fibonacci(n)<<endl;
    cout<<fibonacci2(n)<<endl;
    //cout<<fibonacci3(n)<<endl;
    return 0;
}


    

用备忘录:

#include<iostream>
 
using namespace std;
int f[100];
int fibonacci(int n);
int lookup(int n)
{
    for(int i=1;i<=n;i++)
    {
        f[i]=-1;
    }
    return fibonacci(n);
}
int fibonacci(int n)
{
    if(f[n]!=-1)
    {
        return f[n];
    }
    if(n==1||n==2)
    {
        f[n]=1;
    }
    else
    {
        f[n]=fibonacci(n-2)+fibonacci(n-1);
    }
    return f[n];
}

int main()
{
    int n;
    cin>>n;
    
    cout<<lookup(n)<<endl;

}