上后谈爱情

导航

 

题目:从一段输入的序列中,找出其连续子序列的最大值:k={0,max{A0,A1,A2.....}},Ai是其输入序列的连续子列。

测试数据:

序列:-2 11 -4 13 -5 -2,则最大子序列和为20。

序列:-6 2 4 -7 5 3 2 -1 6 -9 10 -2,则最大子序列和为16。

 

算法一:利用递归:其时间复杂度(Nlog(N))

解析:递归思想是:将序列分为三个部分,左侧部分和、右侧部分和(其中分法用的二分法方式)和包括左右部分整体部分序列和。当序列逐次的遍历到最后只有单个元素后,将相邻两个单元素和这两个元素组成的集合,这三个集合相互比较,得到一个最大值(在这里{0},{1},{0,1}得到最大值 在同{2},{1,2}比较),这里不需要{0,1}{1,2}这样来比较,(这样就可以省略相当一部分相同操作)同样可以得到最大子序列。

代码如下:

#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
vector <int>a;
//采用的是递归来进行算法时间复杂度减少(Nlog(N))

long maxSumRec( int left,int right,int *startpoint,int*endpoint)
{ if(left==right)
{
if(a[left]>0)
return left;
else
return 0;
}

int begin=-1, end=-1;
int centra=(left+right)/2;
int leftStart=left,leftEnd=centra, rightStart=centra+1,rightEnd=right;
long maxleftsum=maxSumRec(left,centra,&leftStart,&leftEnd);
long maxrightsum=maxSumRec(centra+1,right,&rightStart,&leftEnd);

////求出以左边对后一个数字结尾的序列最大值rr
long maxleftBorderSum=0, leftBordersum=0;
for(int i=centra;i>=left;i--)
{
leftBordersum+=a[i];
if(maxleftBorderSum<leftBordersum)
{
maxleftBorderSum=leftBordersum;
begin=i;

}
}

//求出以右边对后一个数字结尾的序列最大值

long maxRightBorderSum = 0, rightBorderSum = 0;

for (int j = centra+1; j <= right; j++)

{

rightBorderSum += a[j];

if (rightBorderSum > maxRightBorderSum)
{
maxRightBorderSum = rightBorderSum;
end=j;

}

}
long c=maxleftBorderSum+ maxRightBorderSum ;
//计算三者中最大值
//long a=maxleftsum, b= maxrightsum, c=maxleftBorderSum+ maxRightBorderSum ;
{
long tmp;
if(maxleftsum>maxrightsum)
{
*startpoint=leftStart;
*endpoint=leftEnd;
tmp=maxleftsum;
}
else
{

tmp=maxrightsum;

}
if(tmp>c)
{
*startpoint=rightStart;
*endpoint=rightEnd;
cout<<*startpoint<<endl;
cout<<*endpoint<<endl;
return tmp;
}
else
{

*startpoint=begin;
*endpoint=end;

return c;
}

}

}

long MaxSequenceValue()
{ int start=-55,end=55;
int k= maxSumRec(0,a.size()-1,&start,&end);
cout<<start<<endl;
cout<<end<<endl;
return k;
}

int main()
{

int num;
while( scanf("%d",&num)==1 )
{
a.push_back(num);

}
long MAX=MaxSequenceValue( );
cout<<MAX<<endl;
return 0;
}

 

 算法4,采用的是联机算法:(由于最大子序列的Start点不可能是负值,所以可以对其省去)

具体代码如下:

 

#include<cstdio>
#include<iostream>
#include<vector>
using namespace std;
vector<int>a;
int N;
int MAXSeq4(int *left1,int *right1)
{
    long maxsum4=0,thissum4=0;int begin=0;
    //求最大子序列中,最大子序列开始值一定不可能是负值,所以我们可以将其抛弃
    for(int j=0;j<a.size();j++)
    {
        
                thissum4+=a[j];
                if(maxsum4<thissum4)
                {
                    maxsum4=thissum4;
                    *left1=begin;
                    *right1=j;
                }
                else if(thissum4<0)
                {
                    thissum4=0;
                    begin=j+1;
                }
    }
    return maxsum4;
}


int main()
{        cout<<"请输入您要输入序列总元素";
        cin>>N;
     int num;int count=0;int max,left=0,right=0;
 while( N-- )
 { 
     //scanf("%d",&num);这句话用来进行测试的
     num=(int)(rand()%100-121);
    // cout<<num<<"  ";
     if(num<0)
        count++;
    a.push_back(num);

 }
         if(count==a.size()-1)
         {
            max=0;
            cout<<"MAX=:"<<max<<endl;

         }
         else
         {
            max=MAXSeq4(&left,&right);
        cout<<"("<<left<<','<<right<<"):"<<max<<endl;
         }
 return 0;
}

 

 

posted on 2016-04-18 16:56  上后谈爱情  阅读(161)  评论(0编辑  收藏  举报