zoukankan      html  css  js  c++  java
  • 求解最大子序列和的四种方法

    1、三重循环暴力求解

    例程:

    int MaxSubsequenceSum(const int A[], int N)
    {
    	int ThisSum, MaxSum, i, j, k;
    	
    	MaxSum = 0;
    	for(int i = 0; i < N; i++)
    		for(int j = i; j < N; j++)
    		{
    			ThisSum = 0;
    			for(k = i; k <= j; k++)
    				ThisSum += A[k];
    			if(ThisSum > MaxSum)
    				MaxSum = ThisSum;
    		}
    	return MaxSum;
    }
    

    分析复杂度:

    复杂度为

    [sum^{n}_{i = 1}(sum_{j = i}^n(j - i)) ]

    [sum_{j = i}^n(j - i) = frac{(n - i)(n - i + 1)}{2} = frac{(n - i)^2}{2} + frac{n- i}{2} ]

    (Rightarrow)

    [sum_{i = 1}^n(frac{(n - i)^2}{2} + frac{n - i}{2}) = O(n^3) ]

    2、两重循环

    上面的三重循环可以撤除一个,以此来获取平方级别的复杂度

    例程:

    
    int MaxSubsequenceSum(const int A[], int N)
    {
    	int ThisSum, MaxSum, i, j;
    	
    	MaxSum = 0;
    	for(int i = 0; i < N; i++)
    	{
    		ThisSum = 0;
    		for(int j = i; j < N; j++)
    		{
    			ThisSum += A[j];
    			
    			if(ThisSum > MaxSum)
    				MaxSum = ThisSum;
    		}
    	}
    	return MaxSum;
    }
    

    易知,复杂度为

    [sum_{i = 1}^{n}(n - i) = O(n^2) ]

    3、分治

    例程:

    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 = MaxSubSum(A, Left, Center);
    	MaxRightSum = MaxSubSum(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 > MaxRightBorerSum)
    			MaxRightBorderSum = RightBorderSum;
    	}
    	
    	return Max3(MaxLeftSum, MaxRightSum, MaxLeftBorderSum + MaxRightBorderSum);
    }
    
    int MaxSubSequenceSum(const int A[], int N)
    {
    	return MaxSubSum(A, 0, N - 1);
    }
    

    [T(n) = 2T(frac{n}{2}) + O(n) ]

    (Rightarrow)

    [T(n) = O(nlogn) ]

    4、联机算法(online algorithm)

    见另一篇文章:https://www.cnblogs.com/fanlumaster/p/13654938.html

  • 相关阅读:
    沟通的5个步骤
    安家博客园,发表感想
    postman 简单教程-实现简单的接口测试
    Postman的基本使用
    面试题-如何测试一个APP
    Fiddler快捷方式导出jmeter脚本,傻瓜式
    Servlet学习(三)
    scala学习(一)
    白底抠图
    Servlet学习(二)
  • 原文地址:https://www.cnblogs.com/fanlumaster/p/13712373.html
Copyright © 2011-2022 走看看