【七】【C语言\动态规划】最大子数组和、环形子数组的最大和、乘积最大子数组,三道题目深度解析

动态规划

动态规划就像是解决问题的一种策略,它可以帮助我们更高效地找到问题的解决方案。这个策略的核心思想就是将问题分解为一系列的小问题,并将每个小问题的解保存起来。这样,当我们需要解决原始问题的时候,我们就可以直接利用已经计算好的小问题的解,而不需要重复计算。

动态规划与数学归纳法思想上十分相似。

数学归纳法:

  1. 基础步骤(base case):首先证明命题在最小的基础情况下成立。通常这是一个较简单的情况,可以直接验证命题是否成立。

  2. 归纳步骤(inductive step):假设命题在某个情况下成立,然后证明在下一个情况下也成立。这个证明可以通过推理推断出结论或使用一些已知的规律来得到。

通过反复迭代归纳步骤,我们可以推导出命题在所有情况下成立的结论。

动态规划:

  1. 状态表示:

  2. 状态转移方程:

  3. 初始化:

  4. 填表顺序:

  5. 返回值:

数学归纳法的基础步骤相当于动态规划中初始化步骤。

数学归纳法的归纳步骤相当于动态规划中推导状态转移方程。

动态规划的思想和数学归纳法思想类似。

在动态规划中,首先得到状态在最小的基础情况下的值,然后通过状态转移方程,得到下一个状态的值,反复迭代,最终得到我们期望的状态下的值。

接下来我们通过三道例题,深入理解动态规划思想,以及实现动态规划的具体步骤。

53. 最大子数组和

题目解析

动态表示

动态表示一般是通过经验+题目得到的。

经验一般是指,以某个位置为结尾,或者以某个位置为开始。

我们可以定义dp[i]表示以下标i为结尾的子数组,所能得到的最大和。

因为所有的子数组都有一个结尾,结尾的元素一定是nums数组的某一个元素。

所以我们可以用这个标准划分状态。

动态转移方程

我们想一想dp[i]的状态能不能由其他的状态推导得出?

dp[i]表示以下标i为结尾的子数组,所能得到的最大和。

dp[i-1]表示以下标i-1为结尾的子数组,所能得到的最大和。

对于以下标i为结尾的子数组,要么该子数组只有下标i一个元素,要么不止i下标一个元素。

如果只有下标i一个元素,那么dp[i]=nums[i]

如果不止下标i一个元素,那么dp[i]=dp[i-1]+nums[i]

因为dp[i]表示的是所能获得的最大和,所以在这两种情况中,我们需要选其中的更大的值。

故状态转移方程为,dp[i]=max(nums[i],dp[i-1]+nums[i])

初始化

根据状态转移方程,我们知道,想要推导出dp[i]需要用到dp[i-1]。

所以我们需要初始化第一个位置的状态,即初始化dp[0]。

dp[0]表示以下标0为结尾的子数组,所能得到的最大和。

很容易得到,dp[0]=nums[0]。

填表顺序

根据状态转移方程,我们知道,想要推导出dp[i]需要用到dp[i-1]。

所以我们应该从左往右填写dp表。

返回值

我们需要得到所有子数组中,最大的连续和,所以我们需要遍历所有情况,记录最大值。

代码实现

 
int maxSubArray(int* nums, int numsSize) {//dp[i]表示以下标i结尾的连续子数组所能得到的最大和int n=numsSize;int dp[n];int ret=nums[0];dp[0]=nums[0];for(int i=1;i<n;i++){dp[i]=fmax(nums[i],dp[i-1]+nums[i]);ret=fmax(dp[i],ret);}return ret;
}

我们可以在填表的时候,每填写一个状态就比较一次,如果比最大值大就记录。

最后返回ret就是最大和。

918. 环形子数组的最大和

题目解析

动态表示

动态表示是由经验+题目意思得到的。

经验一般是以某个位置为结尾,或者以某个位置为开始。

根据题目分析,我们需要记录最大和和最小和。

所以我们应该定义f[i]、g[i],分别表示以i下标为结尾的子数组所能得到的最大和、最小和。

即,f[i]表示以i下标为结尾的子数组所能得到的最大和。

g[i]表示以i下标为结尾的子数组所能得到的最小和。

动态转移方程

我们想一想能不能由其他状态推导出f[i],g[i]?

f[i]表示以i下标为结尾的子数组所能得到的最大和。

g[i]表示以i下标为结尾的子数组所能得到的最小和。

f[i-1]表示以i-1下标为结尾的子数组所能得到的最大和。

g[i-1]表示以i-1下标为结尾的子数组所能得到的最小和。

对于f[i],以i下标为结尾的子数组,分两种情况,第一种情况是这个子数组只有i下标一个元素,第二种情况是不止i下标一个元素。

如果只有i下标一个元素,所能得到的最大和就是nums[i]本身。

如果不止i下标一个元素,所能得到的最大和就是f[i-1]+nums[i]。

所以f[i]=max(nums[i],f[i-1]+nums[i])

同理,g[i]=min(nums[i],g[i-1]+nums[i])

初始化

根据动态转移方程,我们知道想要推导出i下标状态需要用到i-1位置的状态。

所以我们需要初始化第一个位置的状态。

即,f[0]=nums[0],g[0]=nums[0]

填表顺序

根据状态转移方程,我们知道想要推导出i下标状态需要用到i-1位置的状态。

所以我们应该从左往右开始填写。

返回值

我们应该返回两种情况下的最大和。

要么最大和对应子数组在nums数组中间,要么最大和对应子数组在nums数组首尾。

当最大和对应子数组在nums数组中间时,我们只需要一个变量记录f[i]中的最大值即可

当最大和对应子数组在nums数组首尾时,我们需要一个变量记录g[i]中的最小值,然后还需要判断min是不是等于sum,如果是相等的,sum-min就没有意义。如果不相等,sum-min就是首尾情况的最大和。

返回这两种情况的最大和即可。

代码实现

 
int maxSubarraySumCircular(int* nums, int numsSize) {int n=numsSize;int sum=0;for(int i=0;i<n;i++){sum+=nums[i];}int f[n];int g[n];//f:最大和//g:最小和int max=nums[0],min=nums[0];f[0]=nums[0];g[0]=nums[0];for(int i=1;i<n;i++){f[i]=fmax(nums[i],f[i-1]+nums[i]);g[i]=fmin(nums[i],g[i-1]+nums[i]);max=fmax(max,f[i]);min=fmin(min,g[i]);}return sum==min?max:fmax(sum-min,max);}

152. 乘积最大子数组

题目解析

动态表示

动态表示是由经验+题目意思得到的。

经验一般是以某个位置为结尾,或者以某个位置为开始。

根据题目意思我们需要求最大乘积值。

所以我们可以定义dp[i]表示以i下标结尾的子数组所能得到的最大乘积值。

(修正动态表示,f[i]表示以i下标结尾的子数组所能得到的最大乘积值

g[i]表示以i下标结尾的子数组所能得到的最小乘积值)

动态转移方程

我们想一想dp[i]能不能由其他状态推导得出?

dp[i]表示以i下标结尾的子数组所能得到的最大乘积值。

dp[i-1]表示以i-1下标结尾的子数组所能得到的最大乘积值。

(正数乘以最大值就是最大值,正数乘以最小值就是最小值)

(负数乘以最大值就是最小值,负数乘以最小值就是最大值)

对于dp[i],如果nums[i]>0,dp[i]=dp[i-1]*nums[i]

如果nums[i]<0,dp[i]=(i-1位置的最小乘积值)*nums[i]

所以我们发现只存储最大乘积值是不够的。所以我们修正动态表示。

(修正动态表示,f[i]表示以i下标结尾的子数组所能得到的最大乘积值

g[i]表示以i下标结尾的子数组所能得到的最小乘积值)

对于f[i],如果nums[i]>0,f[i]=f[i-1]*nums[i]

如果nums[i]<0,f[i]=g[i-1]*nums[i]

如果nums[i]=0,f[i]=0

对于g[i],如果nums[i]>0,g[i]=g[i-1]*nums[i]

如果nums[i]<0,g[i]=f[i-1]*nums[i]

如果nums[i]=0,f[i]=0

如果nums[i]=0,是可以把这种情况归类于nums[i]<0这种情况或者nums[i]>0这种情况中,因为当nums[i]=0,

f[i]=f[i-1]*nums[i]

f[i]=g[i-1]*nums[i]

g[i]=g[i-1]*nums[i]

g[i]=f[i-1]*nums[i]

都是等于0,所以动态转移方程可以写为

int x=nums[i]; int y=nums[i]*f[i-1]; int z=nums[i]*g[i-1]; f[i]=fmax(x,fmax(y,z)); g[i]=fmin(x,fmin(y,z));

初始化

根据动态转移方程,我们知道想要推导i位置的状态,需要i-1位置的状态,所以我们需要初始化第一个位置的状态。

即, f[0]=nums[0]; g[0]=nums[0];

填表顺序

根据状态转移方程,我们知道想要推导i位置的状态,需要i-1位置的状态,所以我们应该从左往右开始填写,同时填写两个表格。

返回值

f[i]表示以i下标结尾的子数组所能得到的最大乘积值

g[i]表示以i下标结尾的子数组所能得到的最小乘积值

我们要求的是最大乘积值,所以需要遍历f[i]数组中所有的值,找出最大值。

代码实现

 
int maxProduct(int* nums, int numsSize) {int n=numsSize;int f[n];int g[n];f[0]=nums[0];g[0]=nums[0];int ret=nums[0];for(int i=1;i<n;i++){int x=nums[i];int y=nums[i]*f[i-1];int z=nums[i]*g[i-1];f[i]=fmax(x,fmax(y,z));g[i]=fmin(x,fmin(y,z));ret=fmax(ret,f[i]);}return ret;
}

结尾

今天我们学习了动态规划的思想,动态规划思想和数学归纳法思想有一些类似,动态规划在模拟数学归纳法的过程,已知一个最简单的基础解,通过得到前项与后项的推导关系,由这个最简单的基础解,我们可以一步一步推导出我们希望得到的那个解,把我们得到的解依次存放在dp数组中,dp数组中对应的状态,就像是数列里面的每一项。最后感谢您阅读我的文章,对于动态规划系列,我会一直更新,如果您觉得内容有帮助,可以点赞加关注,以快速阅读最新文章。

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。

同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。

谢谢您的支持,期待与您在下一篇文章中再次相遇!

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

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

相关文章

成交订单的条件是什么?搞清楚后再去开发客户

订单&#xff0c;也就是贵司某个产品满足了客户的需求&#xff0c;双方达成合作意向&#xff0c;说白也就是商品需求和供给的匹配。 那么&#xff0c;想要客户下订单&#xff0c;就要弄明白什么样的产品才能满足客户的需求匹配&#xff1f;了解客户关心的点在哪些方面&#xf…

python脚本抢各大平台大额优惠卷

文章目录 python脚本抢各大平台大额优惠卷写在前面准备阶段一、所需工具二、ChromeDriver下载教程 三、Seleuinm安装1、打开cmd&#xff0c;输入如下命令 开始抢券淘宝脚本京东抢购脚本 python脚本抢各大平台大额优惠卷 写在前面 当电商平台上演盛大的购物狂欢时&#xff0c;如…

SpringBoot3 基础特性

1. SpringApplication 1.1. 自定义 banner 类路径添加banner.txt或设置spring.banner.location就可以定制 banner推荐网站&#xff1a;Spring Boot banner 在线生成工具&#xff0c;制作下载英文 banner.txt&#xff0c;修改替换 banner.txt 文字实现自定义&#xff0c;个性化…

数据驱动与数据安全,自动驾驶看得见的门槛和看不见的天花板

作者 |田水 编辑 |德新 尽管心理有所准备&#xff0c;2023年智能驾驶赛道的内卷程度还是超出了大多数人的预期。 这一年&#xff0c;汽车价格战突然开打&#xff0c;主机厂将来自销售终端的价格压力&#xff0c;传导到下游智驾供应商&#xff0c;于是&#xff0c;市面上出现…

医院云HIS系统源码,saas多医院版,适用于专科医院、集团医院、基层医院

医院云HIS系统源码&#xff0c;自主研发&#xff0c;自主版权&#xff0c;电子病历病历4级 系统概述&#xff1a; 一款满足基层医院各类业务需要的云HIS系统。该系统能帮助基层医院完成日常各类业务&#xff0c;提供病患挂号支持、病患问诊、电子病历、开药发药、会员管理、统…

数据结构:单调栈

1.单调栈 单调栈是一种数据结构&#xff0c;其中存放的数据应该是有序的&#xff0c;所以单调栈也有单调递减栈和单调递增栈 单调递增栈&#xff1a;栈顶到栈底的元素大小是从小到大 单调递减栈&#xff1a;栈顶到栈底的元素大小是从大到小 单调栈主要就是用来求一个给定序列中…

【unity3D-粒子系统】粒子系统主模块-Particle System篇

&#x1f497; 未来的游戏开发程序媛&#xff0c;现在的努力学习菜鸡 &#x1f4a6;本专栏是我关于游戏开发的学习笔记 &#x1f236;本篇是unity的粒子系统主模块-Particle System 基础知识 Particle System 介绍&#xff1a;粒子系统的主模块&#xff0c;是必需的模块&#x…

ESP8266 ESP-01/01s 工作模式与固件下载烧录接线

注意点&#xff1a; ESP8266 ESP-01与 ESP8266 ESP-01s接线类似 。本文使用的是ESP8266 ESP-01 WIFI模块&#xff0c;详细信息见如下图片。本文固件下载的是ESP8266 的MQTT固件&#xff0c;下载其它固件流程一致。本文使用的是杜邦线连接面包板来进行使用&#xff0c;与使用开发…

《人生何处不相逢》歌词解析

很少仔细思考某首歌的歌词&#xff0c;上次解析还是费玉清的《一剪梅》&#xff0c;不过那个在我的小红书上&#xff0c;这首歌曲子罗大佑的作品&#xff0c;简宁填词&#xff0c;陈慧娴演唱&#xff0c;表达了对缘分的无常和缘尽的伤感&#xff0c;以及缘分的可贵 1.随浪随风…

DRF从入门到精通五(路由组件、认证组件、权限组件、频率组件及认证、权限源码分析)

文章目录 一、路由组件REST framework提供了两个routeraction装饰器 二、认证组件(Authentication)三、权限组件(Permissions)内置权限类 四、频率组件(Throttling)五、权限组件源码分析六、认证组件源码分析 一、路由组件 对于视图集ViewSetMixin&#xff0c;我们除了可以自己…

YOLOv8可视化:引入多种可视化CAM方法,为科研保驾护航

💡💡💡本文内容:调用pytorch下的CAM可视化库,支持十多种可视化方法,打开“黑盒”,让YOLOv8变得相对可解释性 收录 YOLOv8原创自研 https://blog.csdn.net/m0_63774211/category_12511737.html?spm=1001.2014.3001.5482 💡💡💡全网独家首发创新(原创),适…

代理IP使用的IP协议有哪些?优质的动态IP有什么特征?

一、代理IP使用的IP协议 代理IP使用的主要IP协议有三种&#xff1a;HTTP协议、SOCKS协议和FTP协议。 1. HTTP协议&#xff1a;是最常用的协议&#xff0c;通过HTTP协议传输的数据是明文&#xff0c;它可以在任意多的机器上使用&#xff0c;并且工作方式是可靠的。它是一个无状态…

Vue Echarts 多折线图只有一条X轴(合并X轴数据并去重排序) - 附完整示例

echarts&#xff1a;一个基于 JavaScript 的开源可视化图表库。 目录 效果 一、介绍 1、官方文档&#xff1a;Apache ECharts 2、官方示例 二、准备工作 1、安装依赖包 2、示例版本 三、使用步骤 1、在单页面引入 echarts 2、指定容器并设置容器宽高 3、数据处理&am…

经验分享:构建知识库管理系统只需要这几步

导语&#xff1a; 在当今信息爆炸的时代&#xff0c;构建一个高效的知识库管理系统对于企业来说至关重要。一个好的知识库管理系统可以帮助企业集中管理和共享知识和信息&#xff0c;提高团队的协作效率和创新能力。本文将分享构建知识库管理系统的几个关键步骤&#xff0c;帮…

[Linux] MySQL数据库的备份与恢复

一、数据库备份的分类和备份策略 1.1 数据库备份的分类 1&#xff09;物理备份 物理备份&#xff1a;对数据库操作系统的物理文件&#xff08;如数据文件、日志文件等&#xff09;的备份。 物理备份方法&#xff1a; 冷备份(脱机备份) &#xff1a;是在关闭数据库的时候进…

3D视觉方案的优势

随着机器视觉在工业领域的应用逐渐深入&#xff0c;传统的 2D 视觉方案已经趋向成熟&#xff0c;应用局限性也已经显现出来。 2D 视觉方案易受照明条件影响&#xff0c;一致性和稳定性难以保证&#xff0c;且无法实现三维高精度测量和定位&#xff0c; 3D 视觉方案应运而生&…

第二百三十二回

文章目录 1. 概念介绍2. 实现方法3. 代码与效果3.1 示例代码3.2 运行效果 4. 内容总结 我们在上一章回中介绍了"自定义TimePicker组件"相关的内容&#xff0c;本章回中将继续介绍该组件.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 我们在上一章回…

奇富科技跻身国际AI学术顶级会议ICASSP 2024,AI智能感知能力迈入新纪元

近日&#xff0c;2024年IEEE声学、语音与信号处理国际会议ICASSP 2024&#xff08;2024 IEEE International Conference on Acoustics, Speech, and Signal Processing&#xff09;宣布录用奇富科技关于语音情感计算的最新研究成果论文“MS-SENet: Enhancing Speech Emotion Re…

vue中的路由

目录 一、路由基础 路由机制 1.声明路由对象数组 2.创建路由器实例对象 3.将路由器实例注册vue根实例 4.通过router-link标签访问组件 5.路由导航守卫 二、动态路由匹配 响应路由参数的变化/监听路由url地址栏参数变化&#xff1f; 一、路由基础 路由机制 通过路由加载组件…

11.map 容器

11、map 容器 简介&#xff1a; map 中所有元素都是 pairpair 中第一个元素为 key&#xff08;键值&#xff09;&#xff0c;起到索引作用&#xff0c;第二个元素为 value&#xff08;实值&#xff09;所有元素都会根据元素的键值自动排序 本质&#xff1a; map/multimap 属…