给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。

示例:

输入: [-2,1,-3,4,-1,2,1,-5,4],
输出: 6
解释: 连续子数组 [4,-1,2,1] 的和最大,为 6

暴力:暴力列举所有可能的连续子数组,算法复杂度O(N^3)
算法1:
 1 int MaxSubseqSum1(int A[], int N)
2 {
3 int ThisSum, MaxSum = 0;
4 int i,j,k;
5
6 for (i = 0; i < N; i++) //i对应子列左端位置
7 {
8 for (j = i; j < N; j++) //j对应子列右端位置
9 {
10 ThisSum = 0;
11 for (k = i; k <= j; k++) //一段子列的和
12 {
13 ThisSum += A[k];
14 }
15 if(ThisSum > MaxSum)
16 MaxSum = ThisSum; //更新
17 }
18 }
19 return MaxSum;
20 }

每次从i加到j,我们都必须要经历k循环,i+(i+1)...j,所以每次j循环后都要经历一个k循环从i加到j,想想完全没有必要,可以直接在前一个子序
列的基础上加一个元素,所以k循环是没有必要的。
因此优化算法在相同的i不同的j只需要在j-1次的循环的基础上累加一项即可,算法复杂度更新为O(N^2)
算法2:

 1 int MaxSubseqSum2(int A[], int N)
2 {
3 int ThisSum, MaxSum = 0;
4 int i,j,k;
5
6 for (i = 0; i < N; i++) //i对应子列左端位置
7 {
8 ThisSum = 0;
9 for (j = i; j < N; j++) //j对应子列右端位置
10 {
11 ThisSum += A[k]; //在上一个子序列和的基础上加一个数
12
13 if(ThisSum > MaxSum)
14 MaxSum = ThisSum;
15 }
16 }
17 return MaxSum;
18 }

算法3:分治把大问题拆成小问题,然后逐个解决,最后合并起来。

把数组一分为二,分别递归(即左右两边再分成小的左右两边)的去解决左右两边问题,得到两边的最大子列和,还有一种情况跨越边界的最大子列和,然后想要的结果就是这三个数之间的最大的那个数。算法复杂度O(NlogN)

 1 int Max3( int A, int B, int C )
2 { /* 返回3个整数中的最大值 */
3 return A > B ? A > C ? A : C : B > C ? B : C;
4 }
5
6 int DivideAndConquer( int List[], int left, int right )
7 { /* 分治法求List[left]到List[right]的最大子列和 */
8 int MaxLeftSum, MaxRightSum; /* 存放左右子问题的解 */
9 int MaxLeftBorderSum, MaxRightBorderSum; /*存放跨分界线的结果*/
10
11 int LeftBorderSum, RightBorderSum;
12 int center, i;
13
14 if( left == right ) { /* 递归的终止条件,子列只有1个数字 */
15 if( List[left] > 0 ) return List[left];
16 else return 0;
17 }
18
19 /* 下面是"分"的过程 */
20 center = ( left + right ) / 2; /* 找到中分点 */
21 /* 递归求得两边子列的最大和 */
22 MaxLeftSum = DivideAndConquer( List, left, center );
23 MaxRightSum = DivideAndConquer( List, center+1, right );
24
25 /* 下面求跨分界线的最大子列和 */
26 MaxLeftBorderSum = 0; LeftBorderSum = 0;
27 for( i=center; i>=left; i-- ) { /* 从中线向左扫描 */
28 LeftBorderSum += List[i];
29 if( LeftBorderSum > MaxLeftBorderSum )
30 MaxLeftBorderSum = LeftBorderSum;
31 } /* 左边扫描结束 */
32
33 MaxRightBorderSum = 0; RightBorderSum = 0;
34 for( i=center+1; i<=right; i++ ) { /* 从中线向右扫描 */
35 RightBorderSum += List[i];
36 if( RightBorderSum > MaxRightBorderSum )
37 MaxRightBorderSum = RightBorderSum;
38 } /* 右边扫描结束 */
39
40 /* 下面返回"治"的结果 */
41 return Max3( MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum );
42 }
43
44 int MaxSubseqSum3( int List[], int N )
45 { /* 保持与前2种算法相同的函数接口 */
46 return DivideAndConquer( List, 0, N-1 );
47 }

算法4:贪心算法(在线处理算法)

每输入一个数据,进行即时处理,在任何一个地方停止输入,算法都能得到正确的解,即总是做出在当前看来最好的选择。

只需遍历一遍数组,算法复杂度为O(N)。

 1 int MaxSubseqSum4(int A[], int N)
2 {
3 int i;
4 int ThisSum, MaxSum;
5 ThisSum = MaxSum = 0;
6
7 for (i = 0; i < N; i++) //向右累加
8 {
9 ThisSum += A[i];
10 if (ThisSum > MaxSum)
11 MaxSum = ThisSum; //发现更大则更新
12 else if (ThisSum > MaxSum) //如果当前子序列为负,因为它不能使后边子列和增大
13 ThisSum = 0; //直接放弃累加
14 }
15 return MaxSum;
16 }

算法5:动态规划(DP)

不断更新dp[i]中的值,表示A数组中以A[i]为结尾的最大子序列和,例如A = [2,3,-6,2,4],则dp = [2,5,-1,2,6],则dp数组中的最大值就是最大子序列和就是6.

只需要遍历一遍数组,算法复杂度O(N)

 1 int MaxSubseqSum1(int A[], int N)
2 {
3 int i;
4 int dp[N];
5 int ThisSum = 0;
6 dp[0] = A[0];
7 for (i = 1; i < N; i++)
8 {
9 if (dp[i]<0 || (i==1 && dp[0]<0)) //如果A[0]就小于0则它并不能使后边序列增大所以不累加,或者后边的子序列和中出现负值
10 {
11 dp[i] = A[i];
12 }
13 else
14 {
15 dp[i] = dp[i - 1] + A[i];
16 }
17 }
18
19 return Max.dp[i];
20 }

DP是根据自己的理解写的,如有不对,请指正谢谢。





暴力+分治+贪心+DP:最大子序列和的更多相关文章

  1. BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP

    BZOJ_3174_[Tjoi2013]拯救小矮人_贪心+DP Description 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀 ...

  2. D. Diverse Garland Codeforces Round #535 (Div. 3) 暴力枚举+贪心

    D. Diverse Garland time limit per test 1 second memory limit per test 256 megabytes input standard i ...

  3. hdu 1257 最少拦截系统【贪心 || DP——LIS】

    链接: http://acm.hdu.edu.cn/showproblem.php?pid=1257 http://acm.hust.edu.cn/vjudge/contest/view.action ...

  4. 洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP

    洛谷 P4093 [HEOI2016/TJOI2016]序列 CDQ分治优化DP 题目描述 佳媛姐姐过生日的时候,她的小伙伴从某宝上买了一个有趣的玩具送给他. 玩具上有一个数列,数列中某些项的值可能会 ...

  5. 【BZOJ-3174】拯救小矮人 贪心 + DP

    3174: [Tjoi2013]拯救小矮人 Time Limit: 1 Sec  Memory Limit: 128 MBSubmit: 686  Solved: 357[Submit][Status ...

  6. 洛谷P4823 拯救小矮人 [TJOI2013] 贪心+dp

    正解:贪心+dp 解题报告: 传送门! 我以前好像碰到过这题的说,,,有可能是做过类似的题qwq? 首先考虑这种显然是dp?就f[i][j]:决策到了地i个人,跑了j个的最大高度,不断更新j的上限就得 ...

  7. 【bzoj5073】[Lydsy1710月赛]小A的咒语 后缀数组+倍增RMQ+贪心+dp

    题目描述 给出 $A$ 串和 $B$ 串,从 $A$ 串中选出至多 $x$ 个互不重合的段,使得它们按照原顺序拼接后能够得到 $B$ 串.求是否可行.多组数据. $T\le 10$ ,$|A|,|B| ...

  8. 【bzoj4007】[JLOI2015]战争调度 暴力+树形背包dp

    题目描述 给你一棵 $n$ 层的完全二叉树,每个节点可以染黑白两种颜色.对于每个叶子节点及其某个祖先节点,如果它们均为黑色则有一个贡献值,如果均为白色则有另一个贡献值.要求黑色的叶子节点数目不超过 $ ...

  9. 【bzoj1495】[NOI2006]网络收费 暴力+树形背包dp

    题目描述 给出一个有 $2^n$ 个叶子节点的完全二叉树.每个叶子节点可以选择黑白两种颜色. 对于每个非叶子节点左子树中的叶子节点 $i$ 和右子树中的叶子节点 $j$ :如果 $i$ 和 $j$ 的 ...

  10. 【bzoj3174】[Tjoi2013]拯救小矮人 贪心+dp

    题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人,我们知道他从脚 ...

随机推荐

  1. python: 获取整个字段转换成列表,并将列表转换成字典

    获取整个字段转换成列表,并将列表转换成字典

  2. wget: 未找到命令

    输入以下命令: yum -y install wget

  3. 使用MediatR和FluentValidation实现CQRS应用程序的数据验证

    本文将重点介绍如何通过MediatR的管道功能将FluentValidation集成到项目中实现验证功能. 什么是CQRS? CQRS(Command Query Responsibility Seg ...

  4. 新一代Kerberos攻击 钻石票据与蓝宝石票据

    新一代Kerberos攻击 | 钻石票据与蓝宝石票据 0x01 前言 在了解票据攻击的过程中,看见了一篇文章使用Rubeus进行钻石票据攻击.但是没有原理,于是抱着学习的心态在Google上寻找文章发 ...

  5. 微服务集成seata完成分布式事务,解决数据不一致问题

    细心的盆友可能已经发现了,我们的跨行转账并没有保证数据一致性,比如小明扣除了100,但是因为各种问题小红在添加100金额的时候遇到了异常,这个时候数据就出现不一致性 我们可以选择seata来进行分布式 ...

  6. 数据库中limit 和 offset 使用区别

    题:查找最晚入职员工的所有信息 1,SELECT * FROM employees ORDER BY hire_date DESC LIMIT 0,1; 解:对列hire_date分组后升序,从下标( ...

  7. 小红书获得小红书笔记详情 API 返回值说明

    ​ item_get_video-获得小红书笔记详情  注册开通 smallredbook.item_get_video 公共参数 名称 类型 必须 描述 key String 是 调用key(必须以 ...

  8. ORM查询一个表中有两个字段相同时,只获取某个值最大的一条

    Table表如下: 获取表中name和hex值相同时age最大的那一条 ORM写法,两次查询 ids = table.values('name', 'age').annotate(id=Max('id ...

  9. 2015-CS

    2015-CS 数据库部分 create table [EMPLOYEE]( [EmpNo] varchar(10) not null primary key, [EmpName] varchar(1 ...

  10. Mysql高级11-后台进程

    一.前言 MySQL的服务实现通过后台多个线程.内存池.文件交互来实现对外服务的,不同线程实现不同的资源操作,各个线程相互协助,共同来完成数据库的服务.MySQL常用的后台线程概括如下,分为Maste ...