最大连续子序列和:动态规划经典题目
来源:互联网 发布:玄空排盘软件下载 编辑:程序博客网 时间:2024/06/10 20:27
【题目】
给定k个整数的序列{N1,N2,…,Nk },其任意连续子序列可表示为{ Ni, Ni+1, …, Nj },其中 1 <= i <= j <= k。最大连续子序列是所有连续子序中元素和最大的一个,例如给定序列{ -2, 11, -4, 13, -5, -2 },其最大连续子序列为{11,-4,13},最大连续子序列和即为20。
【注】:为方便起见,如果所有整数均为负数,则最大子序列和为0。
解决这样一个问题是一个很有趣的过程,我们可以尝试着从复杂度比较高的算法一步一步地推出复杂度较低的算法。
【算法1】
时间复杂度:O(N^3)
int MaxSubSequence(const int A[], int N){ int ThisSum,MaxSum,i,j,k; MaxSum = 0; for(i=0;i<N;i++) { for(j=i;j<N;j++) { ThisSum = 0; for(k=i;k<=j;k++) { ThisSum += A[k]; } if(ThisSum > MaxSum) MaxSum = ThisSum; } } return MaxSum; }
【算法2】
时间复杂度 O(N^2)
int MaxSubSequence(const int A[], int N){ int ThisSum,MaxSum,i,j; MaxSum = 0; for(i=0;i<N;i++) { ThisSum = 0; for(j=i;j<N;j++) { ThisSum += A[j]; if(ThisSum > MaxSum) MaxSum = ThisSum; } } return MaxSum; }
【算法3:递归法(分治法)】
时间复杂度:O(NlogN)
易知,对于一数字序列,其最大连续子序列和对应的子序列可能出现在三个地方。或是整个出现在输入数据的前半部(左),或是整个出现在输入数据的后半部(右),或是跨越输入数据的中部从而占据左右两半部分。前两种情况可以通过递归求解,第三种情况可以通过求出前半部分的最大和(包含前半部分的最后一个元素)以及后半部分的最大和(包含后半部分的第一个元素)而得到,然后将这两个和加在一起即可。
int MaxSubSequence(const int A[],int N) { return MaxSubSum(A,0,N-1); } static int MaxSubSum(const int A[], int Left, int Right) { int MaxLeftSum,MaxRightSum; int MaxLeftBorderSum,MaxRightBorderSum; int LeftBorderSum,RightBorderSum; int Center,i; if(Left == Right) { if(A[Left] > 0) return A[Left]; else return 0; } Center = (Left + Right)/2; MaxLeftSum = MaxSubSequence(A,Left,Center); MaxRightSum = MaxSubSequence(A,Center+1,Right); MaxLeftBorderSum = 0; LeftBorderSum = 0; for(i = Center;i >= Left;i--) { LeftBorderSum += A[i]; if(LeftBorderSum > MaxLeftBorderSum) MaxLeftBorderSum = LeftBorderSum; } MaxRightBorderSum = 0; RightBorderSum = 0; for(i = Center+1;i <= Right;i++) { RightBorderSum += A[i]; if(RightBorderSum > MaxRightBorderSum) MaxRightBorderSum = RightBorderSum; } return Max(MaxLeftSum,MaxRightSum,MaxLeftBorderSum + MaxRightBorderSum); } int Max(int a, int b, int c) { if(a>b&&a>c) return a; else if(b>a&&b>c) return b; else return c; }
【算法四:动态规划法】
时间复杂度:O(N)
int MaxSubSequence(const int A[], int N) { int ThisSum,MaxSum,j; ThisSum = MaxSum =0; for(j = 0;j < N;j++) { ThisSum += A[j]; if(ThisSum > MaxSum) MaxSum = ThisSum; else if(ThisSum < 0) ThisSum = 0; } return MaxSum; }
博客内容转自最大连续子序列和:动态规划经典题目
0 0
- 动态规划经典题目:最大连续子序列和
- 动态规划dp经典题目:最大连续子序列和
- 最大连续子序列和:动态规划经典题目
- 最大连续子序列和:动态规划经典题目(2)
- 最大连续子序列和:动态规划经典题目
- 动态规划经典题目:最大连续子序列和
- [动态规划]最大连续子序列和
- 最大连续子序列和-动态规划
- 最大连续子序列和----动态规划
- 动态规划? 最大连续子序列和
- 动态规划:最大连续子序列和
- 最大连续子序列和-动态规划
- 动态规划_题目1011:最大连续子序列
- HDOJ题目1231最大连续子序列(动态规划)
- 【动态规划】最大连续序列和最大子矩阵
- 动态规划经典实例---求最大连续子序列的和
- Maximum Subarray连续子序列最大和 -- LeetCode(经典动态规划)
- 【面试常见题目之动态规划】连续子序列的最大和(子数组的最大和)
- 这8种武器点亮程序员的个人品牌
- 念数字
- struct usb_interface
- 理解js的事件冒泡
- Android singleTask调用顺序u
- 最大连续子序列和:动态规划经典题目
- 2016年暑假于北京某家创业公司的python实习面经
- 第三章 快速搭建Spring4.x项目
- SQL datediff (时间差)
- Eclipse 安装最新SVN插件
- 梳理
- JAVA设计模式之享元模式Flyweight
- 设计模式之工厂模式
- c++ 之类的前置声明