【C++】动态规划题目总结(随做随更)

文章目录

一. 斐波那契数列模型

解题步骤:

  1. 确定状态表示(最重要):明确dp表里的值所表示的含义
  2. 推导状态转移方程(最难):dpi 等于什么?
  3. 初始化:保证填表的时候不越界
  4. 填dp表:通过前面已经计算过的状态来推导当前状态的值
  5. 返回结果

1. 第 N 个泰波那契数

题目解析

我们对题目给的公式进行转化:

观察公式可以看到,如果要求第 i 个泰波那切数的话,我们只需知道前 i-1、i-2、i-3 的值即可。

算法原理

  • 状态表示:dpi 代表第 i 个泰波那切数
  • 状态转移方程:dp[i] = dp[i-1] + dp[i-2] + dp[i-3]
  • 初始化:dp0 = 1、dp1 = 1、dp2 = 1
  • 填表:根据状态转移方程和初始化的值,使用滑动窗口的方式一直计算最终得到第 i 个泰波那切数。
  • 返回值:第 n 个泰波那切数

编写代码

python 复制代码
class Solution {
public:
    int tribonacci(int n) 
    {
        // 1、建表
        // 2、初始化
        // 3、填表
        // 4、返回值

        vector<int> dp(n+1);

        dp[0] = 0, dp[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];
    }
};

/*
- 时间复杂度:O(n)
- 空间复杂度:O(n)
*/

2. 三步问题


题目解析 :小孩最多一次跳三步,假设要跳到第n级台阶,那最后跳到第n级台阶时的那一步一定是下面三种情况之一:

所以想求跳到第n级台阶有几种方法的话,我们只需知道跳到第 n-1、n-2 和 n-3 台阶时各自有几种方法,然后把它们相加起来即可。

PS:计算时需要注意取模

算法原理

  • 状态表示:dpi 表示 到达i位置时,一共有多少种方法。
  • 状态转移方程:dpi = dpi-1 + dpi-2 + dpi-3
  • 初始化:dp1 = 1 dp2 = 2 dp3 = 4
  • 填表顺序:从左往右
  • 返回值 :dpn

代码实现

cpp 复制代码
class Solution
{
public:
	int waysToStep(int n)
	{
		// 1、处理特殊情况
		if (n == 1) return 1;
		if (n == 2) return 2;
		if (n == 3) return 4;
		// 2、创建dp表
		vector<int> dp(n + 1);
		// 3、初始化
		dp[1] = 1;
		dp[2] = 2;
		dp[3] = 4;
		// 4、填表
		for (size_t i = 4; i <= n; ++i)
			dp[i] = ((dp[i - 1] + dp[i - 2]) % 1000000007 + dp[i - 3]) % 1000000007;
		// 5、返回值
		return dp[n];
	}
};

/*
- 时间复杂度:O(n)
- 空间复杂度:O(n)
*/

3. 使用最小花费爬楼梯


题目解析

解法一:从左往右填表

  • 状态表示:dpi 表示到达i位置时的最小花费
  • 状态转移方程
  • 初始化(保证填表的时候不越界):dp0=dp1=0
  • 填表顺序:从左往右
  • 返回值:因为是从0号台阶开始,所以最后一个台阶的下标为 n-1。最后返回 dpn

代码实现

cpp 复制代码
class Solution
{
public:
	int minCostClimbingStairs(vector<int>& cost)
	{
		// 创建dp表
		size_t n = cost.size();
		vector<int> dp(n + 1);
		// 填表
		for (size_t i = 2; i <= n; ++i)
			dp[i] = min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]);
		// 返回值
		return dp[n];
	}
};

/*
- 时间复杂度:O(n)
- 空间复杂度:O(n)
*/

解法二:从右往左填表

  • 状态表示:dpi 表示从i位置出发,到达楼顶,此时的最小花费

  • 状态转移方程

  • 初始化:dpn-1 = costn-1、dpn-2 = costn-2

  • 填表顺序:从右往左

  • 返回值:min(dp0, dp1)

代码实现

cpp 复制代码
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] = cost[i] + min(dp[i + 1], dp[i + 2]);
		return min(dp[0], dp[1]);
	}
};

/*
- 时间复杂度:O(n)
- 空间复杂度:O(n)
*/
相关推荐
殷色玫瑰8 小时前
C++ string类详解:常用接口、字符串操作与模拟实现
java·linux·c语言·开发语言·数据结构·c++
李游Leo8 小时前
HarmonyOS 7 + Spatial Recon Kit-C++:3DGS 高斯参数的非有限值隔离与可渲染性门禁【鸿蒙心迹】
开发语言·c++·3d·harmonyos
jimy19 小时前
基类没有虚析构函数,基类指针删除派生类对象,行为是未定义的
开发语言·c++
xlq223229 小时前
全面复习2
c++
无名猿9 小时前
移动构造与移动赋值:把资源偷过来
c++·性能优化·内存管理·现代c++·语法基础
All for pursuit.10 小时前
【回溯-7】494.目标和
数据结构·c++·算法·leetcode
白杨尚青10 小时前
C++入门篇(十三):vector(上)——动态数组:构造、空间增长与迭代器失效
开发语言·c++·笔记·算法·stl
(Charon)11 小时前
【C++面试】RAII到底是什么:从资源管理理解C++对象生命周期
c++·算法·面试
无名猿11 小时前
成员初始化列表与初始化顺序陷阱:按声明顺序,不是书写顺序
c++·现代c++·语法基础
91刘仁德11 小时前
传输层协议深度拆解:端口寻址、UDP 报文与 TCP 可靠性机制全解析
linux·网络·c++·网络协议·tcp/ip·udp·c