动态规划——做题五步法

前言

今天来看一下动态规划的题目,动态规划,也是经典算法的一种,更是面试常考的算法

究竟什么是动态规划算法呢,下面是DeepSeek选手给出的答案

定义

动态规划是一种 分阶段求解最优化问题 的算法思想,它通过 拆分问题、存储子问题的解(避免重复计算),最终递推得到全局最优解。 

核心思想

  • 分治思想:将大问题分解为相互重叠的子问题。

  • 记忆化存储:用数组(dp 表)记录子问题的解,避免重复计算。

  • 递推求解:通过状态转移方程,从小问题逐步推导大问题的解。

适用场景

动态规划适用于具有以下特征的问题:

  1. 最优子结构:问题的最优解包含子问题的最优解。
    (例如:最短路径的子路径也是最短的)

  2. 重叠子问题:子问题被重复计算多次。
    (例如:斐波那契数列中 fib(5) 依赖 fib(4) 和 fib(3),而 fib(4) 又依赖 fib(3)

今天我要向大家介绍的是做动态规划算法的基本五步(这里是借鉴b站上讲算法的大佬——代码随想录的想法,大家有空可以去看看人家的算法视频),先通过简单题理解如何运用五步法

到了后面的延申题就不至于毫无思路了

确定dp数组(dp table)以及下标的含义

确定递推公式

dp数组如何初始化

确定遍历顺序

举例推导dp数组

上面的dp数组也算是动态规划里的核心内容吧,就是用他来存储子问题的解

例题

斐波那契数

说了那么多还不如先看看具体题目,咱们具体题目具体分析

原来斐波那契数列也属于动态规划算法,我当初是用递归做的,也没想太多。

递归代码虽然简单,但是复杂度却不尽人意;

斐波那契数列_牛客题霸_牛客网

首先来看看上面的题,题意是求第n个斐波那契数

首先来看看什么是斐波那契数;

就是当n=1,2时,对应的值都是1,当n>2时,f(n)=f(n-1)+f(n-2)

所以会有

1 1 2 3 5 8 13 21

这些数就是斐波那契数

然后再看看上面的五步法

首先来看看第一步,确定dp数组以及下标的含义

这里求的是斐波那契数,那么dp数组自然是存放斐波那契数的,那么dp[i]就表示为第i个斐波那契数吧;

然后第二步,确定递推公式,其实也就是找规律,看看题目要求的数字有什么规律,这里题目已经给出了,当n>2时,满足f(n)=f(n-1)+f(n-2) 剩下的部分再单独处理

接着是第三步,dp数组如何初始化,那么我们知道,dp[i]表示的是第i个斐波那契数,dp[1]=1,dp[2]=1,那么dp[0]呢?

或许应该等于0,这样刚好就与性质对应上了,逻辑也说得通了

第四步,确定遍历顺序,因为动态规划有些题目会存在从后往前遍历的问题,所以这里也要考究一下遍历顺序的问题,这道题比较基础,值也是从小到大的,所以遍历顺序也是从小到大

第五步举例推导一下,这里我们写个伪代码,试试推导一下逻辑能否成立

vector<int> dp(n+1);
dp[0]=0;
dp[1]=1;
for(int i=2;i<n;i++)//由于0,1都已经做处理了,所以遍历从2开始
{
    dp[i]=dp[i-1]+dp[i-2]
}

假设n等于5

dp[3]=2,dp[4]=3,dp[5]=5

似乎和刚刚的手动推导的一样,那我们就把想法变成代码,试试能不能通过

这里正常通过了

时间复杂度是O(n),似乎还能再优化一下,感觉只维护两个值也行?

这里也是成功的把代码的时间复杂度降到了O(1)

跳台阶

跳台阶_牛客题霸_牛客网

想当初第一次看见这道题,竟毫无思路,现在才知道要先分析一下数据

我们先来看看,这似乎也是斐波那契数列

跳的台阶数       跳法
    1            1
    2            2    
    3            3
    4            5
    5            8

那就简单了  dp数组存放的是跳台阶时可能有的跳法,dp[i]则表示的是第i层台阶总共有的跳法

递推公式也简单 满足f(n)=f(n-1)+f(n-2)就行

初始化的话,由于不存在第0层,直接考虑第一层和第二层

dp[1]=1
dp[2]=2

遍历顺序也是从小到大

最后写个伪代码,简单推导一下

vector<int> dp(n+1)
dp[1]=1;
dp[2]=2;
for(int i=3;i<=n;i++)
{
    dp[i]=dp[i-1]+dp[i-2]
}

假如是3层台阶

跳一遍一层,跳一遍两层

跳三遍一层

跳一遍两层,跳一遍一层

刚好是三次,现在验证一下思路

刚好过了

还可以和上面一样,优化一下思路

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值