【算法小课堂】动态规划

动态规划

动态规划相信大家都知道,动态规划算法也是新手在刚接触算法设计时很苦恼的问题,有时候觉得难以理解,但是真正理解之后,就会觉得动态规划其实并没有想象中那么难。网上也有很多关于讲解动态规划的文章,大多都是叙述概念,讲解原理,让人觉得晦涩难懂,即使一时间看懂了,发现当自己做题的时候又会觉得无所适从。我觉得,理解算法最重要的还是在于练习,只有通过自己练习,才可以更快地提升。话不多说,接下来,下面我就通过一个例子来一步一步讲解动态规划是怎样使用的,只有知道怎样使用,才能更好地理解,而不是一味地对概念和原理进行反复琢磨。

本题很明显

  1. 状态表示dp【i】为第n个泰波那契数,img
  2. 编辑本题是第一种情况,后面的题目我们会不断遇到1,2,3的情况,我们后面再细讲
  3. 而状态转移方程为题目也直接给了出来, Tn+3 = Tn + Tn+1 + Tn+2,状态转移方程: Tn = Tn -1+ Tn-2 + Tn-3
  4. 初始化(防止越界的情况):本题很明显Tn-3的时候当,n小于3的时候会出现越界的情况,因此我们要提前初始化好dp【0】 ,dp【1】,dp【2】
  5. 填表顺序: 左到右img编辑
  6. 返回值;dp【n】

细节问题:

  • 当n<3的时候,就不需要进行Tn = Tn -1+ Tn-2 + Tn-3计算因此就可以直接返回

空间优化问题:

本题如果我们按照上面的写法的话,就需要开辟一个n+1大小的vector数组dp,当我们在计算第n个位置的时候,我们只需要n-1,n-2,n-3的位置,如果前面还有n-4和n-5都不需要的

img

因此我们就可以直接用三个变量a,b,c来优化,使得空间复杂度为o(1)

面试题 08.01. 三步问题

分析一下题目的意思:

当从0号台阶到1号台阶,只有1种方法;

当从0号台阶到2号台阶,我们可以直接从0号台阶蹦到2号台阶,也可以从0-1-2,总共两种解法

当从0号台阶到3号台阶,我们可以从0号直接蹦到3号台阶,也可以0-1-2-3和0-2-3和0-1-3,总共4种解法

img编辑 眼尖的同学这个时候以及发现了状态转移方程了,我们注意一下(以到4号台阶为例):我们可以看成从1号到4的方法数+2号到4号的方法数+3号到4号的方法数

  1. 因此我们的状态表示dp【i】就表示到达第i号台阶的方法数
  2. 状态转移方程:img编辑

此时有的同学会有一个疑问:就是我从i-2号台阶到i号台阶的时候不是有两种情况:

  • i-2到i
  • i-2先到i-1再到i号台阶

其实不然:i-2先到i-1的这种情况以及是包含在i-1到i的方法数中

  1. 初始化(防止越界的情况):本题很明显Tn-3的时候当,n小于3的时候会出现越界的情况,因此我们要提前初始化好dp【0】 ,dp【1】,dp【2】
  2. 填表顺序: 左到右
  3. 返回值;dp【n】

解题思路:

本题的状态表示是通过经验+题目要求得出的

状态表示:dp[i]代表以i位置结尾的所有解码方法总和

状态转移方程:

img编辑

我们就观察以i位置结尾的数字串,此时有两种情况:

  • s[i]单独解码
  • s[i]和s[i-1]一起解码

先说s【i】单独解码的情况,当解码成功时,也就是s【i】代表的数字属于【1,9】,则dp【i】+=dp【i-1】,失败的话就是0了

再来就是 s[i]和s[i-1]一起解码 的情况:当解码成功也就是这两个数字属于【10,26】,则dp【i】+=dp【i-2】,失败也是0

初始化:dp【0】当s【0】属于1-9,dp【0】=1,s【0】=0的话dp【0】=0

dp【1】的话,此时就有两个数字,就分为两种情况,两个数字分开单独解码和两个数字一起解码,单独解码的话s【1】代表的数字属于【1,9】,dp【1】++,两个数字一起解码的话,当解码成功也就是这两个数字属于【10,26】,则dp【1】++

填表顺序:从左导游

返回值;dp[n-1]

解题代码:

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

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

91. 解码方法

处理边界问题及初始化问题的的技巧:

我们可以给dp数组多开一个位置,也就是开n+1个空间,使整个数组向右移动一位

这样我们原本的dp【1】也可以移到循环中进行计算了!!!

img编辑

这里的0,1,2等都是下标

因此我们多出来一个位置0号下标的值是多少呢?

因为我们后面要计算dp【2】也就是原本的dp【1】的时候会运用到dp【i-2】和dp【i-1】

因为dp【i-1】不会出错,所以我们只需要注意dp【i-2】的正确性

当dp【2】时,也就是两位数字的解码方案数,当我们运用到dp【i-2】的时候,这个是两位数字一起解码,因此dp【i】+=dp【i-2】如果dp【0】为0,即使解码成功也等于没有解码成功,因此这里dp【0】要为1

优化后的代码:

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/621728.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java--业务场景:在Spring项目启动时加载Java枚举类到Redis中(补充)

文章目录 前言步骤测试结果 前言 通过Java–业务场景&#xff1a;在Spring项目启动时加载Java枚举类到Redis中,我们成功将Java项目里的枚举类加载到Redis中了&#xff0c;接下来我们只需要写接口获取需要的枚举值数据就可以了&#xff0c;下面一起来编写这个接口吧。 步骤 在…

mysql-bin日志清理,并设置expire_logs_days时间,mysql占用空间过大问题

mysql-bin日志清理&#xff0c;并设置expire_logs_days时间&#xff0c;mysql占用空间过大问题 文章目录 问题查看mysql配置参数解决全局修改参数清理日志规则手动清理my.cnf 外传 问题 最近发现生产环境的服务器磁盘空间吃紧&#xff0c;查下到底是哪里占用的空间比较大&…

leetcode238:除自身以外数组的乘积

文章目录 1.使用除法&#xff08;违背题意&#xff09;2.左右乘积列表3.空间复杂度为O(1)的方法 在leetcode上刷到了这一题&#xff0c;一开始并没有想到好的解题思路&#xff0c;写篇博客再来梳理一下吧。 题目要求&#xff1a; 不使用除法在O(n)时间复杂度内 1.使用除法&am…

Tomcat Notes: URL Mapping

This is a personal study notes of Apache Tomcat. Below are main reference material. - YouTube Apache Tomcat Full Tutorial&#xff0c;owed by Alpha Brains Courses. https://www.youtube.com/watch?vrElJIPRw5iM&t801s 1、URL Mapping To Resources1.1、What w…

新一代数字原住民:市场痛点与“繁”思维应对之道

随着科技的迅速发展&#xff0c;尤其是互联网的普及&#xff0c;新一代数字原住民经营者已经逐渐成为市场的主力军。不同于传统的消费者&#xff0c;有着独特的消费习惯和心理需求。企业要在这激烈的市场竞争中获得优势&#xff0c;深入了解这一群体的特征和心理、行为&#xf…

有趣的事,讲给有趣的人听

哈哈哈&#xff0c;今天不写技术了&#xff0c;今天分享一下生活&#xff0c;技术我们什么时候都可以学&#xff0c;但是生活更值得我们现在就去更好的体验&#xff01; 两年多的涤生大数据&#xff0c;认识了形形色色的小伙伴&#xff0c;陆续沟通下来6000多人&#xff0c;彼时…

数据库锁表原因、排查、解决

一.场景 场景1场景2二.原因三.排查四.解决方案 一.场景 场景1 锁表通常发生在DML&#xff08; insert 、update 、delete &#xff09; A操作进行全量数据同步&#xff0c;对整个表的粒度进行上锁&#xff0c;导致B操作只能等待A操作完成才能进入插入数据。此时就出现了锁表…

Pandas实战100例 | 案例 14: 数据透视表 - 使用 `pivot_table`

案例 14: 数据透视表 - 使用 pivot_table 知识点讲解 数据透视表是一种常见的数据汇总工具&#xff0c;用于按照一个或多个键对数据进行分类汇总。Pandas 的 pivot_table 函数提供了一种快速创建数据透视表的方法。你可以指定行索引、列索引&#xff0c;以及用于聚合的数据和…

Elasticsearch windows开箱即用【记录】

一、准备工作 安装ES之前要在本机安装好JDK&#xff0c;对应的兼容性见官网链接&#xff1a;https://www.elastic.co/cn/support/matrix ES官网链接&#xff1a;https://www.elastic.co/cn/, 我本机安装的是JDK8&#xff0c;测试使用的是7.3.0版本的ES和Kibana。 1、首先去…

Windows平台程序和Android平台程序的差异

Windows平台程序和Android平台程序的差异 1 Windows平台环境和Android平台JVM虚拟机的差异&#xff1a; 1&#xff09;由于JVM虚拟机上的数据是大端处理的&#xff0c;而Windows平台上的数据是小端的&#xff0c;所以在一些数据的处理上需要进行转换&#xff1b; 2&#xf…

vmware创建嵌套虚拟机

嵌套虚拟机的搭建 在vmware 虚拟机设置中&#xff0c;打开处理器的虚拟化Intel VT-x/EPT 或AMD-V/RVI&#xff08;v&#xff09;配置虚拟机yum 源&#xff0c;安装qemu、qemu-kvm、libvirt从阿里镜像源下载centos iso 阿里源 centos-7-x86准备虚拟机创建所需xml&#xff0c;ce…

Day32 贪心算法 part02 122. 买卖股票的最佳时机 II 55. 跳跃游戏 45. 跳跃游戏 II

贪心算法 part02 122. 买卖股票的最佳时机 II 55. 跳跃游戏 45. 跳跃游戏 II 122. 买卖股票的最佳时机 II 思路&#xff1a;计算每天的利润&#xff0c;利润如果为正&#xff0c;加到结果中去 class Solution { private:int result 0; public:int maxProfit(vector<int&g…

PyTorch项目源码学习(3)——Module类初步学习

torch.nn.Module Module类是用户使用torch来自定义网络模型的基础&#xff0c;Module的设计要求包括低耦合性&#xff0c;高模块化等等。一般来说&#xff0c;计算图上所有的子图都可以是Module的子类&#xff0c;包括卷积&#xff0c;激活函数&#xff0c;损失函数节点以及相…

完成源示例

本主题演示如何创作和使用自己的完成源类&#xff0c;类似于 .NET 的 TaskCompletionSource。 completion_source 示例的源代码 下面的列表中的代码作为示例提供。 其目的是说明如何编写自己的版本。 例如&#xff0c;支持取消和错误传播不在此示例的范围内。 #include <w…

java常见面试题:如何使用Java进行单元测试?

单元测试是软件开发中的一个重要环节&#xff0c;它确保每个单独的代码单元都能按照预期工作。以下是如何使用Java进行单元测试的详细说明&#xff1a; JUnit&#xff1a; JUnit是Java中最流行的单元测试框架。首先&#xff0c;添加JUnit依赖到你的项目中。如果你使用Maven&…

技术学习周刊第 2 期

有关 TLS/SSL 证书的一切 HTTPS 隐私安全的一些实践 关于 TLS 两篇非常好的文章&#xff0c;如果对 TLS 了解不多的话看上面两篇本章就够了。 从传统的 HTTPS 加密通信&#xff0c;到云原生架构下零信任网络所要求的 mTLS 双向认证&#xff0c;TLS 协议已经是服务通信的必备…

VR全景技术如何应用在城市发展,助力城市宣传展示

引言&#xff1a; 随着科技的不断发展&#xff0c;VR全景技术正逐渐渗透到各行各业&#xff0c;其中较为广泛的应用之一便是城市展示。那么VR全景技术如何运用在城市展示领域&#xff0c;这项技术给城市发展带来了哪些好处&#xff1f; 一. VR全景技术简介 1.什么是VR全景技术…

天梯赛 L1-094 剪切粘贴

原题链接 https://pintia.cn/problem-sets/994805046380707840/exam/problems/1649748772841508869?type7&page0 题面 &#xff08;建议点击原题链接查看&#xff0c;复制过来比较乱&#xff0c;只作预览&#xff09; 使用计算机进行文本编辑时常见的功能是剪切功能&am…

怎样制作一本旅游电子相册呢?

​随着数码技术的发展&#xff0c;旅游电子相册已成为越来越多旅游爱好者的必备工具。它不仅能让您随时随地欣赏自己的旅行回忆&#xff0c;还能分享给亲朋好友&#xff0c;甚至上传到社交媒体上&#xff0c;让更多人了解您的旅行故事。那么&#xff0c;如何制作一本精美的旅游…

Postman接口测试之断言,全网最细教程没有之一!

一、断言 在 postman 中我们是在Tests标签中编写断言&#xff0c;同时右侧封装了常用的断言&#xff0c;当然 Tests 除了可以作为断言&#xff0c;还可以当做后置处理器来编写一些后置处理代码&#xff0c;经常应用于&#xff1a; 【1】获取当前接口的响应&#xff0c;传递给…