【动态规划专栏】专题一总结

2024-09-05 01:20

本文主要是介绍【动态规划专栏】专题一总结,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

本专栏内容为:算法学习专栏,分为优选算法专栏,贪心算法专栏,动态规划专栏以及递归,搜索与回溯算法专栏四部分。 通过本专栏的深入学习,你可以了解并掌握算法。

💓博主csdn个人主页:小小unicorn
⏩专栏分类:动态规划专栏
🚚代码仓库:小小unicorn的代码仓库🚚
🌹🌹🌹关注我带你学习编程知识

专题一

  • 第 N 个泰波那契数
  • 三步问题
  • 最小花费爬楼梯
  • 解码方法:
    • 3.初始化
    • 4.填表顺序
    • 5.返回值
  • 斐波那契数
  • 思维导图:

在专题一中,我们重点学习了动态规划的第一种类型:斐波那契模型,在程序中我们用四道题进行了练习与巩固。

第 N 个泰波那契数

来源:第 N 个泰波那契数

在第一题中:发现他跟我们的斐波那契数列其实是很相似的,在解决本题中,我们首先对问题进行了变形:
在这里插入图片描述
我们通过变形,得到了一个递推关系式,第四个数是我们对应前三个数的和。为解决此问题呢,我们通过举例子:引出了dp表的概念
在这里插入图片描述
dp表其实就是一个一维或者二维数组,而我们要做就是将dp表里面的值填满,而其中dp表里面的值就是我们要的答案。
动态规划基本上分为五步:

  • 1.状态表示
  • 2.状态转移方程
  • 3.初始化
  • 4.填表顺序
  • 5.返回值

其中状态转移方程由状态表示推出,而3.4.5步则为处理细节问题。

在第一题中,我们的状态表示为:

dp[i]:表示第i个泰波那契数

根据递推式,我们的状态转移方程为;

dp[i]=dp[i-3]+dp[i-2]+dp[i-1]

这道题其实基本上到这就已经结束了,最后不要忘了初始化以及边界处理即可。

代码实现:

class Solution 
{
public:int tribonacci(int n) {//创建dp表vector<int> dp(n+1);//处理边界if(n==0)return 0;if(n==1||n==2)return 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];}
};

三步问题

来源:三步问题

这道题很有意思,我们分析题目:举几个例子:
在这里插入图片描述
规律还是很好发现的,所以状态表示直接就是:

dp[i]:表示到达i位置时,有多少种方法

在分析状态转移方程时,我们要以i位置的状态,来划分问题:
在这里插入图片描述
到达iu位置的时候,我们要观察,他可以如何到达i位置,可以从i-1位置,也可以从i-2位置过来,还可以从i-3位置过来。

因此状态转移方程:

dp[i]=dp[i-3]+dp[i-2]+dp[i-1]

最后我们分析一下边界情况,分别在3,2,1,0位置取到。

代码实现:

class Solution 
{
public:int waysToStep(int n) {const int MOD=1e9+7;//创建dp表vector<int> dp(n+1);//处理边界条件:if(n==1)return 1;if(n==2)return 2;if(n==3)return 4;//初始化dp[0]=0;dp[1]=1;dp[2]=2;dp[3]=4;for(int i=4;i<=n;i++){dp[i]=((dp[i-3]+dp[i-2])%MOD+dp[i-1])%MOD;}return dp[n];}
};

最小花费爬楼梯

来源:最小花费爬楼梯

本题要小心一点的是:
楼顶是在整个数组外面而不是数组的最后一个位置。
每次爬楼梯只能爬一层或者两层。

本题在确定状态表示,我们还是根据经验,不过这道题当时咱们用了两种办法:

1.以i位置为结尾
2.以i位置为开始

以i位置为结尾:
状态表示:

dp[i]表示:以i位置为结尾时,的最小花费

状态转移方程:
首先,到达i位置有两种情况:
在这里插入图片描述
我们根据最近的一步来划分问题:
在这里插入图片描述
因此,状态转移方程:

dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);

边界情况在0位置和1位置。

第二种方法这里就不再解释了。

代码实现:

class Solution 
{
public:int minCostClimbingStairs(vector<int>& cost) {//创建dp表int n=cost.size();vector<int> dp(n+1);//初始化dp[0]=dp[1]=0;//填表for(int i=2;i<=n;i++){dp[i]=min(dp[i-1]+cost[i-1],dp[i-2]+cost[i-2]);}return dp[n];        }
};

解码方法:

来源:解码方法

对于本题而言就是:

dp[i]表示:以i位置为结尾时,解码方法的总数

在推方程之前,我们先画一下解码的情况:
在这里插入图片描述
分为单独解码和与前一个位置一起解码两种情况:
在这里插入图片描述
而单独解码和一起解码又要分为两种情况,成功和失败。
为什么会失败呢?
举个例子:
在这里插入图片描述
2和5可以一起解码,也可以分开解码,但到0位置时,就会解码错误,自己单独不能解码,要是与后面的6结合,
在这里插入图片描述
会出现之前说的前导0情况,也会解码错误。

因此,本题的状态转移方程为:

dp[i] = dp[i-1]+ dp[i-2]

3.初始化

本题初始化要在下标为0位置与下标为1位置进行初始化:
在这里插入图片描述

  dp[0]=s[0]!='0';//处理边界条件:if(n==1)return dp[0];if(s[0]!='0'&&s[1]!='0')dp[1]+=1;//前两个位置所表示的数:int t=(s[0]-'0')*10+s[1]-'0';if(t>=10&&t<=26)dp[1]+=1;

4.填表顺序

根据状态转移方程,我们计算dp[i]位置的值需要i-1与i-2位置的值,因此我们的填表顺序为:从左往右

5.返回值

我们要解码到最后一个位置,因此:返回dp[n-1]

代码实现:

class Solution 
{
public:int numDecodings(string s) {// 1.创建dp表// 2.初始化// 3.填表// 4.返回值int n=s.size();vector<int> dp(n);dp[0]=s[0]!='0';//处理边界条件:if(n==1)return dp[0];if(s[0]!='0' && s[1]!='0')dp[1]+=1;//前两个位置所表示的数: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]!='0')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];}
};

斐波那契数

来源:斐波那契数

本题很简单,递推式题目都给了,直接上代码:

class Solution 
{
public:int fib(int n) {//创建dp表vector<int> dp(n+1);//处理边界条件:if(n==0)return 0;if(n==1)return 1;//初始化dp[0]=0;dp[1]=1;//填表for(int i=2;i<=n;i++){dp[i]=dp[i-1]+dp[i-2];}return dp[n];}
};

思维导图:

在这里插入图片描述
第一章所有代码以及解题思路画图版图片,以及思维导图都已上传至资源中。

这篇关于【动态规划专栏】专题一总结的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1137565

相关文章

HarmonyOS学习(七)——UI(五)常用布局总结

自适应布局 1.1、线性布局(LinearLayout) 通过线性容器Row和Column实现线性布局。Column容器内的子组件按照垂直方向排列,Row组件中的子组件按照水平方向排列。 属性说明space通过space参数设置主轴上子组件的间距,达到各子组件在排列上的等间距效果alignItems设置子组件在交叉轴上的对齐方式,且在各类尺寸屏幕上表现一致,其中交叉轴为垂直时,取值为Vert

学习hash总结

2014/1/29/   最近刚开始学hash,名字很陌生,但是hash的思想却很熟悉,以前早就做过此类的题,但是不知道这就是hash思想而已,说白了hash就是一个映射,往往灵活利用数组的下标来实现算法,hash的作用:1、判重;2、统计次数;

第10章 中断和动态时钟显示

第10章 中断和动态时钟显示 从本章开始,按照书籍的划分,第10章开始就进入保护模式(Protected Mode)部分了,感觉从这里开始难度突然就增加了。 书中介绍了为什么有中断(Interrupt)的设计,中断的几种方式:外部硬件中断、内部中断和软中断。通过中断做了一个会走的时钟和屏幕上输入字符的程序。 我自己理解中断的一些作用: 为了更好的利用处理器的性能。协同快速和慢速设备一起工作

动态规划---打家劫舍

题目: 你是一个专业的小偷,计划偷窃沿街的房屋。每间房内都藏有一定的现金,影响你偷窃的唯一制约因素就是相邻的房屋装有相互连通的防盗系统,如果两间相邻的房屋在同一晚上被小偷闯入,系统会自动报警。 给定一个代表每个房屋存放金额的非负整数数组,计算你 不触动警报装置的情况下 ,一夜之内能够偷窃到的最高金额。 思路: 动态规划五部曲: 1.确定dp数组及含义 dp数组是一维数组,dp[i]代表

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

软考系统规划与管理师考试证书含金量高吗?

2024年软考系统规划与管理师考试报名时间节点: 报名时间:2024年上半年软考将于3月中旬陆续开始报名 考试时间:上半年5月25日到28日,下半年11月9日到12日 分数线:所有科目成绩均须达到45分以上(包括45分)方可通过考试 成绩查询:可在“中国计算机技术职业资格网”上查询软考成绩 出成绩时间:预计在11月左右 证书领取时间:一般在考试成绩公布后3~4个月,各地领取时间有所不同

git使用的说明总结

Git使用说明 下载安装(下载地址) macOS: Git - Downloading macOS Windows: Git - Downloading Windows Linux/Unix: Git (git-scm.com) 创建新仓库 本地创建新仓库:创建新文件夹,进入文件夹目录,执行指令 git init ,用以创建新的git 克隆仓库 执行指令用以创建一个本地仓库的

poj 2976 分数规划二分贪心(部分对总体的贡献度) poj 3111

poj 2976: 题意: 在n场考试中,每场考试共有b题,答对的题目有a题。 允许去掉k场考试,求能达到的最高正确率是多少。 解析: 假设已知准确率为x,则每场考试对于准确率的贡献值为: a - b * x,将贡献值大的排序排在前面舍弃掉后k个。 然后二分x就行了。 代码: #include <iostream>#include <cstdio>#incl

二分最大匹配总结

HDU 2444  黑白染色 ,二分图判定 const int maxn = 208 ;vector<int> g[maxn] ;int n ;bool vis[maxn] ;int match[maxn] ;;int color[maxn] ;int setcolor(int u , int c){color[u] = c ;for(vector<int>::iter

整数Hash散列总结

方法:    step1  :线性探测  step2 散列   当 h(k)位置已经存储有元素的时候,依次探查(h(k)+i) mod S, i=1,2,3…,直到找到空的存储单元为止。其中,S为 数组长度。 HDU 1496   a*x1^2+b*x2^2+c*x3^2+d*x4^2=0 。 x在 [-100,100] 解的个数  const int MaxN = 3000