求子数组最大和 (非连续)(动态规划)

您所在的位置:网站首页 最大连续子序列和问题动态规划二维数组 求子数组最大和 (非连续)(动态规划)

求子数组最大和 (非连续)(动态规划)

2024-07-11 01:01:05| 来源: 网络整理| 查看: 265

转自出处:http://likecer.com/dp-biggest-sub/

动态规划是种神奇的算法,最开始学习最长上升子序列(LIS)的时候,他让我想起了分治,但是动态规划却解决了子问题重叠的大问题,也就是说同一个子问题不求第二遍。所以说动态规划的实质就是记忆化搜索。

        子数组最大和这个问题是很经典典型的一维DP问题。用一层循环就可以搞定,最普通的DP算法复杂度是O(n),比较理想。

        先描述一下这个问题。给第一个数组,如:2, -3, 2, 4, -1, 5。他的子数组最大和就是2 + 4 + (-1) + 5 = 10,我们可以看出,这里说的子数组不同于LIS/LCS中的子序列,这的子数组是连续的。

        最容易想到的算法,肯定是搜索,从所有可能性当中找出和最大的一种。这种算法的复杂度是指数级的O(2n),是惨绝人寰的。

        所以我们来瞧瞧动态规划的解法。假定数组为a(下标0到n-1),d[i]则表示以a[i]为末尾的最大子数组和。所以上述序列中:

d[0] = 2 d[1] = max(d[0] + a[1] , a[0]) = max(2 + (-3), 2) = max(-1, 2) = 2 d[2] = max(d[1] + a[2], a[1]) = max(2 + 2, 2) = max(4, 2) = 4 … 一次论推,到最后,d[5] = 10。

        从上面可以得知,状态转移方程为:d[i] = max(d[i-1] + a[i], a[i]),成立条件为i > 0,因为i = 0是,d[i-1]显然不对。

        对于这个方程的理解,可以这样想:数组全是整数的时候,显而易见,子数组最大和就成了这个数组求和的问题,如果还用DP来写,d[i]就存储着a[0] – a[i]的和,递推起来就是d[i-1] + a[i](a[i]前面所有数字之和加上a[i])。如果数组含有负数,a[i]就可能比前面的最大和要大了。所以状态转移方程是:max(d[i-1] + a[i], a[i])这么写的。

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 #include ;stdio.h; #include ;stdlib.h; #define max(a,b) (((a);(b))?(a):(b))   int DP ( int a [ ] , int n ) {      int i , ans ;      int * d = malloc ( sizeof ( a ) ) ;      ans = d [ 0 ] = a [ 0 ] ;      for ( i = 1 ; i      int a [ ] = { 2 , - 3 , 2 , 4 , - 1 , 5 } ;      printf ( "%d" , DP ( a , 6 ) ) ;      return 0 ; }

        我看到很多同志喜欢把动态转移方程中的max()用if()语句来代替,虽然效果一样,不过我觉得用max这样直白的表达式可读性更强。有不少同志喜欢定义一个int max(int a, int b)函数来返回a,b中的最大值,不过用宏来定义效率更高,所以我是用define来写的。另外ans = max(d[i], ans)这一句不属于动态转移方程,只是用来更新ans变量记录的最大值的,如果d[i] > ans,ans就应该更新为d[i]。

        求子数组最大和函数中的for()语句,初始时i = 1,这就是因为上面说的,i = 0时,d[i-1]会导致错误。有的版本会在for()循环体中加入判断:if(i > 0),不过这样,就会产生很多次没必要的判断,效率就会变低。

        所以干脆从循环之前初始化d[0],让他和ans都等于a[0]。然后循环从i = 1开始。这种初始化的方法在DP当中也是很常见的。



【本文地址】

公司简介

联系我们

今日新闻


点击排行

实验室常用的仪器、试剂和
说到实验室常用到的东西,主要就分为仪器、试剂和耗
不用再找了,全球10大实验
01、赛默飞世尔科技(热电)Thermo Fisher Scientif
三代水柜的量产巅峰T-72坦
作者:寞寒最近,西边闹腾挺大,本来小寞以为忙完这
通风柜跟实验室通风系统有
说到通风柜跟实验室通风,不少人都纠结二者到底是不
集消毒杀菌、烘干收纳为一
厨房是家里细菌较多的地方,潮湿的环境、没有完全密
实验室设备之全钢实验台如
全钢实验台是实验室家具中较为重要的家具之一,很多

推荐新闻


图片新闻

实验室药品柜的特性有哪些
实验室药品柜是实验室家具的重要组成部分之一,主要
小学科学实验中有哪些教学
计算机 计算器 一般 打孔器 打气筒 仪器车 显微镜
实验室各种仪器原理动图讲
1.紫外分光光谱UV分析原理:吸收紫外光能量,引起分
高中化学常见仪器及实验装
1、可加热仪器:2、计量仪器:(1)仪器A的名称:量
微生物操作主要设备和器具
今天盘点一下微生物操作主要设备和器具,别嫌我啰嗦
浅谈通风柜使用基本常识
 众所周知,通风柜功能中最主要的就是排气功能。在

专题文章

    CopyRight 2018-2019 实验室设备网 版权所有 win10的实时保护怎么永久关闭