动态规划系列之四梅花桩问题
1|0题目
Redraiment是走梅花桩的高手。Redraiment总是起点不限,从前到后,往高的桩子走,但走的步数最多,不知道为什么?你能替Redraiment研究他最多走的步数吗?
例如梅花桩的高度:
结果分析:
6个点的高度各为 2 5 1 5 4 5
如从第1格开始走,最多为3步, 2 4 5
从第2格开始走,最多只有1步,5
而从第3格开始走最多有3步,1 4 5
从第5格开始走最多有2步,4 5
所以这个结果是3
梅花桩问题是最长升序数组问题。
1|1动态规划解题思路
使用动态规划解题,需要题目符合动态规划的解决思路。动态规划解题思路是:
- 将大的问题拆解成小一点问题,小问题和大问题的解决思路是类似的
- 小问题之间的关系能完成大问题的最优解
通常拆解问题的方法有两种,一种是二分法,把数组拆成两个。第二种是将将数组逐个递减,拆解成多个小数组。对于本体来说,第二种方式比较适合。
小规模问题和大规模问题之间有某种联系,这种联系就是动态转移方程。通过小规模问题的解决,能够解决大规模问题,直到解决最终的问题。
题目是要求数组 [2,5,1,5,4,5]中最长的升序数组。可以按照动态规划的思路,将大问题拆解成小问题。求6个元素的最长升序,可以拆解成求5个,同理求5个元素的,可以拆解成求4个。最后一直到1个。
各个小问题之间有一定联系,通过找到小问题之间的联系,求出最优解。小问题之间的联系就是状态转移方程。
1|2建立数学模型
求最多的步数,但不知道是从哪一步开始算最多。所以就创建一个数组dp,数组dp中存储从第一个梅花桩到当前梅花桩的步数。因为求的步数,最少也走一步,所以dp的初始值就是
1|3状态转移方程
当前梅花桩最多的步数,就是拿当前梅花桩逐个和前面的梅花桩比较,当前梅花桩高就比较是比当前小的梅花桩的最大值+1大 还是 该梅花桩本身的值大。通俗来说就是找出梅花桩数值小的。即:
下标为0时,dp数组
2 | 5 | 1 | 5 | 4 | 5 |
---|---|---|---|---|---|
1 | 1 | 1 | 1 | 1 | 1 |
下标为1时,dp数组。
因为 5 比 2大,所有,dp[0] + 1 > dp[1],所以dp[1]=1+1=2
2 | 5 | 1 | 5 | 4 | 5 |
---|---|---|---|---|---|
1 | 2 | 1 | 1 | 1 | 1 |
下标为2时,dp数组:
1 < 5, 1< 2,所以dp数组不变,dp[2] = 1
2 | 5 | 1 | 5 | 4 | 5 |
---|---|---|---|---|---|
1 | 2 | 1 | 1 | 1 | 1 |
下标为3时,dp数组:
5 > 1,所以dp[3] = max(dp[2]+1,dp[3]) = max(2,1) = 2
同时,5 > 2 ,所以dp[3] = max(2,dp[0]+1) = max(2,2) = 2。
所以dp[3] = 2
2 | 5 | 1 | 5 | 4 | 5 |
---|---|---|---|---|---|
1 | 2 | 1 | 2 | 1 | 1 |
下标为4时,dp数组:
4 > 1 ,dp[4] = max(dp[4],dp[2]+1) = max(1,2) = 2
2 | 5 | 1 | 5 | 4 | 5 |
---|---|---|---|---|---|
1 | 2 | 1 | 2 | 2 | 1 |
下标为5时,dp数组:
5 > 4 ,dp[5] = max(dp[5],dp[4]+1) = max(1,3) = 3
5 > 1 ,dp[5] = max(3,1) = 3
5 > 2 ,dp[5] = max(3,1) = 3
2 | 5 | 1 | 5 | 4 | 5 |
---|---|---|---|---|---|
1 | 2 | 1 | 2 | 2 | 3 |
1|4边界值
边界值很清晰就是第一个梅花桩就一步,也就是dp[1,x,x,x,x,x]
2|0代码实现
3|0小结
梅花桩问题的的巧妙之处在于构建了一个dp数组,该数组中存储了到下标i最长升序个数。然后比较arr[i]和arr前面的所有元素的值,如果arr[i]大于前面的元素的值,那么也就是说arr[i]是升序的数组的下一个元素。但如果arr[i]大于很多个前面的元素的话,就要选择一个最大的值,所以循环比较i和之前的元素,取一个最大值。
4|0数组类动态规划解法
最大和子数组
和最长升序数组
这两个问题能代表着数组类动态规划的求解方式,两个问题的相似之处为:
a. 都将问题转化成以求解第i个元素为结尾的问题
b. 构建dp数组,填充以第i个元素为结尾的最优解
c. 都将大规模问题拆解成小规模问题
d. 小规模问题小到极限有一个边界值,最大和的边界为只有一个元素时就是自身,最长升序的边界为只有一个元素时升序值为1
这四个规律也是求解数组类动态规划问题的四个步骤
同时两个问题也有不同之处:
a. 最大和子数组,dp数组中代表着以i为结尾的数组的最大值,下一个值只和上一个值有关,保证连续性
b. 最长升序数组,dp数组中代表这以i为结尾的升序数组的个数。下一个值与前面所有的值都有关联,要拿到前面值中的最大值。因为其不需要保证连续性,所有需要遍历前面的dp。最大和子数组只需要比较前一个。
__EOF__

本文链接:https://www.cnblogs.com/goldsunshine/p/13221674.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理