码迷,mamicode.com
首页 > 其他好文 > 详细

0.分治永远大于顺序?关于最大子序列和问题的思考

时间:2018-10-21 23:23:04      阅读:319      评论:0      收藏:0      [点我收藏+]

标签:...   code   穷举   order   长度   color   i++   const   str   

p17. 2.4.3 最大子序列和的问题的解

 题目:给定整数A1,A2,......,AN,k=i~jAk的最大值(如果所有整数都为负数,则最大子序列和为0)

书中给出了四种不同的算法,时间复杂度依次降低,下面我简单描述一下这四种算法

第一种:穷举法

求出所有子序列和,比较得出最大的

最简单想到的代码,效率十分低下,原因是没有利用数列的连贯性,对数列元素反复检索造成浪费

三层嵌套循环,时间复杂度

T(N)=O(N3)

 

int 
Maxsubsum(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++)              /*开始按照确定的元素个数选出数列并计算子列和,较大者覆盖Maxsum,较小者在ThisSum中被丢弃*/
                ThisSum += A[k];

            if(ThisSum>Maxsum)
                Maxsum=ThisSum;
        }

    return Maxsum;
}

 

第二种:改良后的穷举法

 

顾名思义,这种方法对方法一进行了改良.

当第选定了子序列的首项后,无需对子序列长度进行再次分组,直接顺序列出所有该首项下的子数列即可,减去了一次循环。

实际上换汤不换药

时间复杂度依旧为幂函数级

T(N)=O(N2)

int 
Maxsubsum(const int A[],int N)
{
    int ThisSum,Maxsum,i,j,k;
    
    Maxsum=0;                     
    for(i=0;i<N;i++)//确定各个子序列的首项
    {
        ThisSum=0;
        for(k=i;k<=j;k++)/*开始按照确定的元素个数选出数列并计算子列和,较大者覆盖Maxsum,较小者在ThisSum中被丢弃*/
            {
                ThisSum += A[k];

                if(ThisSum>Maxsum)
                Maxsum=ThisSum;
            }
    }

    return Maxsum;
}

 

第三种:分治法


这是我们今天着重要探讨的第一种算法。

先上代码。

 1 #include "stdio.h"
 2 int
 3 MaxSubSum(const int A[],int left,int right)//left,right分别为数列数组第一个元素和最后一个元素的下标
 4 {
 5     int Maxleftsum,Maxrightsum;
 6     int Maxleftbordersum,Maxrightbordersum;
 7     int leftbordersum,rightbordersum;
 8     int Center,i;
 9 
10     if(left==right)    /*base case*/
11         if(A[left]>0)
12             return A[left];
13         else
14             return 0;
15 
16 
17     Center=(left+right)/2;
18     Maxleftsum=MaxSubSum(A,left,Center);
19     Maxrightsum=MaxSubSum(A,Center+1,right);
20 
21     Maxleftbordersum=0;leftbordersum=0;
22     for(i=Center;i>=left;i--)
23     {
24         leftbordersum +=A[i]
25         if(leftbordersum>Maxleftbordersum)
26             Maxleftbordersum=leftbordersum;
27     }
28 
29     Maxrightbordersum=0;rightbordersum=0;
30     for(i=Center+1;i<=right;i++)
31     {
32         rightbordersum +=A[i]
33         if(rightbordersum>Maxrightbordersum)
34             Maxrightbordersum=rightbordersum;
35     }
36 
37     return Max(Maxleftbordersum,Maxrightbordersum,Maxrightbordersum+Maxleftbordersum)
38 
39 }

 看起来可能有些复杂哈,我第一次看也是半天看不懂,没有这方面的基础。

我们先来看一个简单的问题来理解啥叫分治。

0.分治永远大于顺序?关于最大子序列和问题的思考

标签:...   code   穷举   order   长度   color   i++   const   str   

原文地址:https://www.cnblogs.com/clclcl/p/9824453.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!