【动态规划】斐波那契数列模型

简介: 【动态规划】斐波那契数列模型

动态规划(斐波那契数列模型)

1. 第 N 个泰波那契数

题目链接

  1. 状态表示
    dp[i]所表示的含义,那么这个状态表示怎么来的那?

题目要求、经验根据题目要求、分析问题的过程中发现重复子问题

  1. 状态转移方程
  2. dp[i]等于什么。根据这题的题目我们发现
    d[i] = dp[i - 1] + dp[i - 2] + dp[i - 3]
  3. 初始化
    保证填表的时候不越界
  4. 填表顺序
    为了填写当前的状态,所需的状态已经完成了
  5. 返回值
    这个题目的返回值当然就是dp[n]
  6. AC代码:
class Solution 
{
public:
    int tribonacci(int n) 
    {
        if (n == 0 || n == 1) return n;
        vector<int> dp(n + 1);
        dp[0] = 0, dp[1] = 1, dp[2] = 1;
        for (int i = 3; i <= n; i++)
        {
            dp[i] = dp[i - 1] + dp[i - 2] + dp[i - 3];
        }
        return dp[n];
    }
};

优化之后:

AC代码:

class Solution 
{
public:
    int tribonacci(int n) 
    {
        if (n == 0) return 0;
        if (n == 1 || n == 2) return 1;
        int a = 0, b = 1, c = 1, d = 0;
        for (int i = 3; i <= n; i++)
        {
            d = a + b + c;
            a = b;
            b = c;
            c = d;
        }
        return d;
    }
};

2. 三步问题

题目链接

  1. 状态表示
    dp[i]表示:到达i位置时,一共有多少中走法
  2. 状态转移方程
  3. 初始化
  4. 填表
  5. 返回值

AC代码:

class Solution
{
    const int mod = 1e9 + 7;
public:
    int waysToStep(int n)
    {
        if (n == 1) return 1;
        if (n == 2) return 2;
        if (n == 3) return 4;
        vector<int> dp(n + 1);
        dp[1] = 1, dp[2] = 2, dp[3] = 4;
        for (int i = 4; i <= n; i++)
        {
            dp[i] = ((dp[i - 1] + dp[i - 2]) % mod + dp[i - 3]) % mod;
        }
        return dp[n];
    }
};

这个题目三个值都加起来,再取模是不行的。这里我们没计算一次加法(乘法)都要进行一次取模运算

3. 使用最小花费爬楼梯

题目链接

解法一

  1. 状态表示
    dp[i]表示到达i位置的最小花费
  2. 状态转移方程

  1. 初始化
  2. 填表顺序
  3. 返回值

AC代码:

class Solution 
{
public:
    int minCostClimbingStairs(vector<int>& cost) 
    {
        int len = cost.size();
        vector<int> dp(len + 1);
        for (int i = 2; i <= len; i++)
        {
            dp[i] = min((dp[i - 1] + cost[i - 1]), (dp[i - 2] + cost[i - 2]));
        }
        return dp[len];
    }
};

解法二

  1. 状态表示
    dp[i]从i位置出发,到达楼顶所需的最小花费
  2. 状态转移方程

  3. 初始化
    dp[n - 1] = cost[n - 1], dp[n - 2] = cont[n - 2]
  4. 填表
    从左往右
  1. 返回值
    min(dp[0], dp[1])

AC代码:

class Solution 
{
public:
    int minCostClimbingStairs(vector<int>& cost) 
    {
        int n = cost.size();
        vector<int> dp(n);
        dp[n - 1] = cost[n - 1], dp[n - 2] = cost[n - 2];
        for (int i = n - 3; i >= 0; i--)
        {
            dp[i] = min((dp[i + 1] + cost[i]), (dp[i + 2] + cost[i]));
        }
        return min(dp[0], dp[1]);
    }
};

4. 解码方法

题目链接

  1. 状态表示
    以i位置为结尾,有多少种解码方法
  2. 状态转移方程

  3. 初始化
    dp[0] = 1 或者0
    dp[1]也有三种情况 0 、1 、2
  1. 填表
  2. 返回值

AC代码:

class Solution 
{
public:
    int numDecodings(string s) 
    {
        int n = s.size();
        vector<int> dp(n + 1);
        if (s[0] == '0') dp[0] = 0;
        else dp[0] = 1;
        if (n == 1) return dp[0];
        if (s[1] >= '1' && s[1] <= '9') dp[1] += dp[0];
        int t = (s[0] - '0') * 10 + s[1] - '0';
        if (t >= 10 && t <= 26) dp[1] += 1;
        for (int i = 2; i < n; i++)
        {
            if (s[i] >= '1' && s[i] <= '9') dp[i] += dp[i - 1];
            int t = (s[i - 1] - '0') * 10 + s[i] - '0';
            if (t >= 10 && t <= 26) dp[i] += dp[i - 2];
        }
        return dp[n - 1];
    }
};

还可以使用辅助节点的方式来处理这个题目的边界问题:

需要注意的是:

  1. 辅助节点里面的值要保证后续填表是正确的
  2. 下标的映射关系
相关文章
|
8月前
|
算法 C++
【动态规划】斐波那契数列模型(C++)
【动态规划】斐波那契数列模型(C++)
|
9月前
|
算法
算法修炼-动态规划之斐波那契数列模型
算法修炼-动态规划之斐波那契数列模型
|
4月前
动态规划——斐波那契模型
本文介绍了动态规划的基本步骤及其在几个典型问题中的应用。首先概述了动态规划的四个关键步骤:状态表示、状态转移方程、初始化及填表顺序,并说明了如何确定返回值。接着通过具体实例讲解了第 N 个泰波那契数、三步问题、使用最小花费爬楼梯以及解码方法等问题的求解过程,详细阐述了每一步的具体实现方法与代码示例。最后还讨论了如何优化初始化过程以简化编码。
43 4
动态规划——斐波那契模型
|
算法 JavaScript 前端开发
☮斐波那契数列与动态规划
☮斐波那契数列与动态规划
136 0
☮斐波那契数列与动态规划
动态规划| 【斐波那契数列模型 】|1137.第N个泰波那锲数
动态规划| 【斐波那契数列模型 】|1137.第N个泰波那锲数
|
算法 Windows
算法 | 详解斐波那契数列问题
算法 | 详解斐波那契数列问题
187 0
算法 | 详解斐波那契数列问题
|
算法
|
算法
算法练习——(6)斐波那契数列前20个
在数学上有一个著名的斐波那契数列,它的规律为:1,1,2,3,5,8,13,21……,请编程输出其前20个数字。
188 0
|
8月前
|
算法 Java 测试技术
斐波那契数列的四种实现算法
斐波那契数列的四种实现算法
182 3
|
算法 Java
【算法】斐波那契数列
主要内容: 斐波那契数列(兔子问题) 递归算法和递推算法 斐波那契数列(兔子问题) 问题描述:刚出生的兔子,长到第三个月开始(忽略月份大小)就可以繁殖下一代。假如1月1日抱来一公一母两只兔子,那么3月1日时,就会生出第一代兔子,并且正好也是一公一母。
1361 0

热门文章

最新文章