最大子串和
来源:互联网 发布:大数据的弱点有几方面 编辑:程序博客网 时间:2024/05/16 11:08
Description
Given a sequence a[1],a[2],a[3]……a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.
分析:
一个经典问题,对于一个包含负值的数字串array[1…n],要找到他的一个子串array[i…j](0<=i<=j<=n),使得在array的所有子串中,array[i…j]的和最大。
这里我们需要注意子串和子序列之间的区别。子串是指数组中连续的若干个元素,而子序列只要求各元素的顺序与其在数组中一致,而没有连续的要求。对于一个元素数为n的数组,其含有2^n个子序列和n(n+1)/2个子串。如果使用穷举法,则至少需要O(n^2)的时间才能得到答案。卡耐基梅隆大学的Jay Kadane的给出了一个线性时间算法,我们就来看看,如何在线性时间内解决最大子串和问题。
要说明Kadane算法的正确性,需要两个结论。首先,对于array[1…n],如果array[i…j]就是满足和最大的子串,那么对于任何k(i<=k<=j),我们有array[i…k]的和大于0。因为如果存在k使得array[i…k]的和小于0,那么我们就有array[k+1…j]的和大于array[i…j],这与我们假设的array[i…j]就是array中和最大子串矛盾。
其次,我们可以将数组从左到右分割为若干子串,使得除了最后一个子串之外,其余子串的各元素之和小于0,且对于所有子串array[i…j]和任意k(i<=k<=j), 有array[i…k]的和大于0。此时我们要说明的是,满足条件的和最大子串,只能是上述某个子串的前缀,而不可能跨越多个子串。我们假设array[p…q],是array的和最大子串,且array[p…q],跨越了array[i…j],array[j+1…k]。根据我们的分组方式,存在 i<=m<=j 使得array[i…m]的和是array[i…j]中的最大值,存在 j+1<=n<=k使得array[j+1…n]的和是array[j+1…k]的最大值。由于array[m+1…j]使得array[i…j]的和小于0。此时我们可以比较array[i…m]和array[j+1…n],如果array[i…m]的和大于array[j+1…n]则array[i…m]>array[p…q],否array[j+1…n]>array[p…q],无论谁大,我们都可以找到比array[p…q]和更大的子串,这与我们的假设矛盾,所以满足条件的array[p…q]不可能跨越两个子串。对于跨越更多子串的情况,由于各子串的和均为负值,所以同样可以证明存在和更大的非跨越子串的存在。对于单元素和最大的特例,该结论也适用。
根据上述结论,我们就得到了Kadane算法的执行流程,从头到尾遍历目标数组,将数组分割为满足上述条件的子串,同时得到各子串的最大前缀和,然后比较各子串的最大前缀和,得到最终答案。我们以array={−2, 1, −3, 4, −1, 2, 1, −5, 4}为例,来简单说明一下算法步骤。通过遍历,可以将数组分割为如下3个子串(-2),(1,-3),(4,-1,2,1,-5,4),这里对于(-2)这样的情况,单独分为一组。各子串的最大前缀和为-2,1,6,所以目标串的最大子串和为6。
参考 http://blog.csdn.net/joylnwang/article/details/6859677
#include<iostream> #define MAXSIZE 100 using namespace std; int MaxSum(int[],int); int main(void) { int n; int array[MAXSIZE]; while(cin>>n) { for(int i=0;i<n;i++) { cin>>array[i]; } cout<<MaxSum(array,n)<<endl; } return 0; } int MaxSum(int array[],int n) { int b=0; int sum=0; for(int i=0;i<n;i++) { if(b>0) { b+=array[i]; } else { b=array[i]; } if(b>sum) { sum=b; } } return sum; }
- 最大子串和
- 最大和子串
- 子串最大和
- 最大子串和
- 最大子串和
- 最大和子串
- 最大子串和
- 最大子串和
- 最大子串和
- 最大子串和
- 最大子串和
- 最大子串和
- 最大子串和
- 最大子串和
- 最大子串和
- 最大子串和
- 最大子串和
- 最大连续子串和
- WinINet
- Java就业指导
- Jmeter和loadrunner的异同
- SQL基础笔记(四)
- codeforces 628B
- 最大子串和
- LIST_ENTRY数据结构
- 基础总结
- Windows平台分布式架构实践 - 负载均衡(下)
- ARM的位置无关程序设计
- RecycleView和CardView的简单介绍和用法
- 遍历二叉树的全部方法(递归+非递归)
- cocos 2dx 3.12 学习笔记(六) DartGameDemo
- Java笔记 - 接口