代码改变世界

多种方式求fibonacci数列

  youxin  阅读(453)  评论(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;

}
复制代码

 

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示