编程语言
首页 > 编程语言> > 算法设计实验三(5)——两段最大子段和问题

算法设计实验三(5)——两段最大子段和问题

作者:互联网

pan.baidu.com/s/1w-VSMWmr9ntEWWdxZoD4Yw 
码:jnlh 

算法分析与设计第 3 次实验

 

时间

 

2020.5.17

  

 

 实验名称

 

两段最大子段和问题

 

实验目的

 

通过在线实验,要求深度掌握动规算法的问题描述、算法设计思想、程序设计。

 

实验原理

 

利用动规与分治思想,根据题目所给出的条件,求解问题,计算出最小总误时惩罚。

 

 

 

 

实验步骤

 

 问题描述:

  

 即要求求得一个数组的两段子段和的最大值;

 

 问题分析:

   求得一个数组的两段子段和的最大值,可以考虑将数组分为两段,分别当作一个数组来进行最大子段和的求解,然后进行求和;问题的关键在于如何对数组进行划分,也就是划分的位置;很明显从1到n都有可能会是划分的位置,所以需要遍历一遍;

   但是简单的遍历加最大子段和求解的话时间复杂度会是O(n^2),无法达到题目要求,因此需要动态规划的方法来进行简单的处理;

 

 算法思想:

   首先用dp[i]表示数组从1到i的最大子段和,根据最大子段和的思想,遍历一次数组即可实现dp[i]的求解;接着逆序遍历,这样就可以求出i+1到n的最大子段和max了,再将dp[i]与max相加即可实现划分位置为i的两段数组的最大子段和;逆序遍历结束后就实现了所有划分位置的遍历,此时就可以得到最大得两段子段和了,整个方法仅仅遍历了两次数组,时间复杂度降为O(n)。

 

算法步骤:

① 循环读入数据;

② 首先顺序遍历数组,按最大子段和得思想求得dp[i](1=<i<=n);

③ 逆序遍历数组,以得到i+1到n的最大子段和max,令max+dp[i]就可以完成以i为断点的两段最大子段和,如果该值比当前的最大值大,那么则更新最大值;

 

 

关键代码

 

关键代码(带注释)

1. 顺序求解dp[i]

 

 利用最大子段和的算法思想进行求解;

2. 逆序遍历数组以得到i+1到n的最大子段和

完成位置i的划分以及两段最大子段和的求解,大于最大值则更新;

 

测试结果

 

 

运行结果截图及分析

对于题目样例:

   

运行正确;

 对于测试数据

 

 

正确accept;

时间复杂度分析:

 对每一组输入样例来说,只需要遍历两次数组即可完成,因此时间复杂度为O(n); 

 空间复杂度分析:

 最少需要O(n)来存储dp;

 

 

 

实验心得

 

通过这道问题,我进一步的理解了动态规划算法的最优子结构,通过局部最优一步一步的推导出最终的整体最优;对于最大子段和问题的理解也进一步加深,该问题就是最大子段和问题的一个变化,通过这个问题实现了如何将学习的简单的动规算法应用到更难的题目中。

标签:遍历,最大,子段,算法,数组,两段,dp
来源: https://blog.csdn.net/weixin_43973089/article/details/116212178