算法修炼-动态规划之斐波那契数列模型

简介: 算法修炼-动态规划之斐波那契数列模型

一、动态规划的算法原理

       这是本人动态规划的第一篇文章,所以先阐述一下动态规划的算法原理以及做题步骤。动态规划本人的理解就是通过题目所给的条件正确地填满dp表(一段数组)。首先要先确定好dp表每个位置的值所代表的含义是什么,然后通过题目条件以及经验推出状态转移方程,第三个就是初始化,确定填表顺序以及保证填表不越界,最后输出题目所需的结果,大致就是这个思路。

二、斐波那契数列模型例题分析

1137. 第 N 个泰波那契数 - 力扣(LeetCode)

本题的思路较为简单,状态转移方程已经给出,直接上代码:

class Solution {
public:
    int tribonacci(int n) 
    {
        vector<int> v1(n+1);
        //初始化
        if(n == 1)
        return 1;
        else if(n == 2)
        return 1;
        else if(n == 0)
        return 0;
        v1[0] = 0;
        v1[1] = 1;
        v1[2] = 1;
        
        for(int i = 3; i <= n; i++)
        {
            v1[i] = v1[i-1] + v1[i-2] + v1[i-3];
        }
        return v1[n];
    }
};

面试题 08.01. 三步问题 - 力扣(LeetCode)

解析:

       假设小孩此时正处于某一台阶上,那他是如何到达这一台阶的呢?是不是他有可能是从该台阶的前一个台阶跳上来的,也可能是从该台阶的前两个台阶跳上来的,也可能是从该台阶的前三个台阶跳上来的,所以小孩到某一台阶就有三种可能情况,也即dp表中某个位置的值就是这个位置前三个位置的值相加,从而确定出了状态转移方程。

class Solution {
public:
    int waysToStep(int n) 
    {
        //创建dp表
        vector<int> v1(n+1);
        if(n ==1)
        return 1;
        if(n == 2)
        return 2;
        if(n == 3)
        return 4;
        //初始化
        v1[1] = 1;v1[2] = 2; v1[3] = 4;
        for(int i = 4; i <= n; i++)
        {
            //确定状态转移方程,这里需要注意,加数的和可能会越界,根据题目要求要对1000000007取模
            v1[i] = ((v1[i-1] + v1[i-2]) % 1000000007 + v1[i-3])%1000000007;
        } 
        return v1[n];
    }
};

746. 使用最小花费爬楼梯 - 力扣(LeetCode)

解析:

       要确定每一级楼梯最低花费,通过比较前两级楼梯,确定应该加的值,从而确定状态转移方程。

class Solution {
public:
    int minCostClimbingStairs(vector<int>& cost) 
    {
        int length = cost.size();
        //dp表
        vector<int> MinCost(length);
        //初始化
        for(int i = 0; i<cost.size(); i++)
        {
            MinCost[i] = cost[i];
        }
        //状态转移方程
        for(int i = 2; i<length; i++)
        {
            if(MinCost[i-1] < MinCost[i-2])
            {
                MinCost[i] += MinCost[i-1];
            }
            else
            {
                MinCost[i] += MinCost[i-2];
            }
        }
        if(MinCost[cost.size() - 1] < MinCost[cost.size() - 2])
        {
            return MinCost[cost.size() - 1];
        }
        else
        {
            return MinCost[cost.size() - 2];
        }
    }
};

91. 解码方法 - 力扣(LeetCode)

解析:

       选定一个位置作为结尾,如果这个位置的值不为零,就看其能否与前一个位置的值组成合法编码,如果能,这个位置的值就是它的前一个位置加上它的前前一个位置的值,如果不能,这个位置的值就是它的前一个位置的值;如果这个位置的值为零,就看其能否与前一个位置的值组成合法编码,如果能,这个位置的值就是它的前前一个位置的值。

class Solution {
public:
    int numDecodings(string s) 
    {
        int len = s.length();
        int arr[len];
        const char* str;
        str = s.c_str();
        for(int i = 0; i<len; i++)
        {
            arr[i] = str[i] - 48;
        }
        //处理特殊情况
        if(arr[0] == 0)
        {
            return 0;
        }
        else if(len == 1 && arr[0] != 0)
        {
            return 1;
        }
        for(int i = 1; i<len; i++)
        {
            //例:30
            if(arr[i] == 0 && (arr[i-1] >2))
            {
                return 0;
            }
            //例:1001
            else if(i+1 < len && arr[i] == 0 && arr[i+1] == 0)
            {
                return 0;
            }
        }
        for(int i = 0; i<len; i++)
        {
            cout << arr[i] << " ";
        }
        //dp表
        vector<int> vect(len+1);
        
        
        //初始化
        vect[0] = 1;vect[1] = 1;
        //状态转移方程
        for(int i = 2; i < vect.size(); i++)
        {
            if(arr[i-1] != 0)
            {
                if(arr[i-2] != 0 && ((arr[i-1] + arr[i-2]*10) <= 26))
                {
                    vect[i] = vect[i-1] + vect[i-2];
                }
                else
                {
                    vect[i] = vect[i-1];
                }
            }
            else
            {
                vect[i] = vect[i-2];
            }
        }
        return vect[len];
    }
};
目录
打赏
0
0
0
0
3
分享
相关文章
|
2天前
|
算法系列之动态规划
动态规划(Dynamic Programming,简称DP)是一种用于解决复杂问题的算法设计技术。它通过将问题分解为更小的子问题,并存储这些子问题的解来避免重复计算,从而提高算法的效率。
17 4
算法系列之动态规划
扩散模型=进化算法!生物学大佬用数学揭示本质
在机器学习与生物学交叉领域,Tufts和Harvard大学研究人员揭示了扩散模型与进化算法的深刻联系。研究表明,扩散模型本质上是一种进化算法,通过逐步去噪生成数据点,类似于进化中的变异和选择机制。这一发现不仅在理论上具有重要意义,还提出了扩散进化方法,能够高效识别多解、处理高维复杂参数空间,并显著减少计算步骤,为图像生成、视频合成及神经网络优化等应用带来广泛潜力。论文地址:https://arxiv.org/pdf/2410.02543。
38 21
单纯接入第三方模型就无需算法备案了么?
随着人工智能的发展,企业接入第三方模型提升业务能力的现象日益普遍,但算法备案问题引发诸多讨论。根据相关法规,无论使用自研或第三方模型,只要涉及向中国境内公众提供算法推荐服务,企业均需履行备案义务。这不仅因为服务性质未变,风险依然存在,也符合监管要求。备案内容涵盖模型基本信息、算法优化目标等,且需动态管理。未备案可能面临法律和运营风险。建议企业提前规划、合规管理和积极沟通,确保合法合规运营。
机器学习算法的优化与改进:提升模型性能的策略与方法
机器学习算法的优化与改进:提升模型性能的策略与方法
356 13
机器学习算法的优化与改进:提升模型性能的策略与方法
【动态规划篇】穿越算法迷雾:约瑟夫环问题的奇幻密码
【动态规划篇】穿越算法迷雾:约瑟夫环问题的奇幻密码
【潜意识Java】蓝桥杯算法有关的动态规划求解背包问题
本文介绍了经典的0/1背包问题及其动态规划解法。
56 5
基于模糊PI控制算法的龙格库塔CSTR模型控制系统simulink建模与仿真
本项目基于MATLAB2022a,采用模糊PI控制算法结合龙格-库塔方法,对CSTR模型进行Simulink建模与仿真。通过模糊控制处理误差及变化率,实现精确控制。核心在于将模糊逻辑与经典数值方法融合,提升系统性能。
基于HMM隐马尔可夫模型的金融数据预测算法matlab仿真
本项目基于HMM模型实现金融数据预测,包括模型训练与预测两部分。在MATLAB2022A上运行,通过计算状态转移和观测概率预测未来值,并绘制了预测值、真实值及预测误差的对比图。HMM模型适用于金融市场的时间序列分析,能够有效捕捉隐藏状态及其转换规律,为金融预测提供有力工具。
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
194 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型

热门文章

最新文章

AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等