1.1 最大子序列求和

  • 题目大意:给出一序列,求该序列的子序列和最大的子序列。

  • 下面共有四种算法:程序运行时间依次降低,最佩服的是最后的联机算法,时间已达到O(N).

  • 注意C++中的函数调用与传值

  • 下面分析四种算法:关于每种程序的运行时间,我们只关注他的最坏情况即可。

    • 算法一,有三个大循环,假设第一个循环的大小N,每个循环都考虑最坏的情况,则总数为 O(N),
      使用开销的思路推一下,精确分析可知,最大开销: N1i=0N1j=ijk=i1 ,该和指出此程序三次循环被执行了多少次,由内到外求值,首先我们有
      k=ij1=ji+1

      然后我们可以得到
      j=iN1(ji+1)=(Ni+1)(Ni)2

      继续:
      i=0N1(Ni+1)(Ni)2=i=1N(Ni+1)(Ni+2)2

      =12i=1Ni2(N+32)i=1Ni+12(N2+3N+2)i=1N1

      =12N(N+1)(2N+1)6(N+32N(N+1)2+N2+3N+22N)

      =N3+3N2+2N6

      所以算法一的最大消费为O( N3 )。
 #include<iostream>
 #include<vector>
 #include<algorithm>
 using namespace std;
//最大子序列求和
//算法一
//穷举法
int maxsubsum(const vector &a)
{
    int maxsum=0;
    for(int i=0;i<a.size();i++)
     for(int j=i;j<a.size();j++)
    {
        int ThisSum=0;
        for(int k=i;k<=j;k++)
        {
            ThisSum+=a[k];
        }
        if(ThisSum>maxsum)
            maxsum=ThisSum;
    }
    return maxsum;
}
//算法二
//对穷举法进行优化
int maxsubsum1(const vector &a)
{
    int maxsum=0;
    for(int i=0;i<a.size();i++)
    {
        int ThisSum=0;
        for(int j=i;j<a.size();j++)
        {
            ThisSum+=a[j];
            if(ThisSum>maxsum)
            maxsum=ThisSum;
        }
    }
    return maxsum;
}
//算法三
//分治法
int maxsumrec(const vector<int> &a,int left,int right)
{
    if(left==right)
    {
        if(a[left]>0)
            return a[left];
        else
            return 0;
    }
    int center=(left+right)/2;
    int maxleftsum=maxsumrec(a,left,center);
    int maxrightsum=maxsumrec(a,center+1,right);
    int maxleftbordersum=0,leftbordersum=0;
     int lrmax=max(maxleftsum,maxrightsum);
    for(int i=center;i>=left;i--)
    {
         leftbordersum+=a[i];
         if(leftbordersum>maxleftbordersum)
            maxleftbordersum=leftbordersum;
    }
    int maxrightbordersum=0,rightbordersum=0;
    for(int i=center+1;i<=right;i++)
    {
        rightbordersum+=a[i];
        if(rightbordersum>maxrightbordersum)
            maxrightbordersum=rightbordersum;

    }
    return max(lrmax,maxleftbordersum+maxrightbordersum);
}

int maxsubsum2(const vector <int> &a)
{
     return maxsumrec(a,0,a.size()-1);
}
//算法四
//联机算法
int maxsubsum3(const vector<int >&a)
{
    int MaxSum=0,ThisSum=0;
    for(int j=0;j<a.size();j++)
    {
        ThisSum+=a[j];
        if(ThisSum>MaxSum)
            MaxSum=ThisSum;
        if(ThisSum<0)
         ThisSum=0;
    }
    return MaxSum;
}
int main()
{
   int input[10];
   for(int i=0;i<5;i++)
   {
       cin>>input[i];
   }
   //注意这里是去给vector容器初始化赋值的时候,区间是[begin,end];
   vector<int>inputVetor(&input[0],&input[4]);
   cout<<maxsubsum(inputVetor)<<endl;
   cout<<maxsubsum1(inputVetor)<<endl;
   cout<<maxsubsum2(inputVetor)<<endl;
   cout<<maxsubsum3(inputVetor)<<endl;
   return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值