最大连续子段和

RT,求一数组中元素的最大连续子段和。

方法一。

  不考虑超时的影响,可以使用循环暴力解决,a[i][j]表示i是开头元素,j为结尾元素,需要使用三层循环,时间复杂度为0(n^3);

 

#include<iostream>
using namespace std;
int b[100][100];
int main()
{
    int a[100];
    int n,k;
    cin>>n;
    for(k=0;k<n;++k)
    cin>>a[k];
    int i,j;
    for(i=0;i<n;++i)
    for(j=i;j<n;++j)
    for(k=i;k<=j;++k)
    {
      b[i][j]=b[i][j]+a[k];
    }
    int max=-222;
    for(int s=0;s<n;++s)
    for(int B=0;B<n;++B)
    if(b[s][B]>max)
    max=b[s][B];
    cout<<max<<endl;
    system("pause");
    return 0;
} 
        
    

方法二。

  方法一中的a[i][j],可以由Sum[j]-Sum[i-1]到,到使时间复杂度降为O(n^2),代码略~

方法三。时间复杂度O(n).

  利用动态规划,由于我是看别人才理解此算法的,所以说说我的理解吧。

#include<iostream>
using namespace std;
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
      int n,a[100001];
      memset(a,0,100001);
      cin>>n;
      for(int i=0;i<n;++i)
      cin>>a[i];
      int temp=0,max=-32222,k=1;
      for(int j=0;j<n;++j)
      {
      temp=temp+a[j];                    //子段之间的相加
      if(temp>max)
      {
      max=temp;                              //保存最大值的信息
      }
      if(temp<0)                         //舍弃之前的子段
      {
                temp=0;
      }
      }
      cout<<max<<endl;
    }
    system("pause");
    return 0;
}


举个例子,a[4]={-11,-8,9,2}; 显然最大子段和是 9+2=11;

该代码从头到尾扫描一次,如果只有一项,则最大子段和是它本身,不管是否为负数还是正数。

假设第二项为正数的话,显然最大子段和就是第二项本身了,该怎样解决了呢,这样想,因为这是求连续子段和,倘若该项的前n-1项连续子段和为负数,则最大子段和max就会改变,因为一个数加上一个负数,值会减小。所以当前n-1项连续子段和为负数时,就舍弃这一段,从头开始。但注意,最大连续子段和中的元素可以允许有负数的存在,此时就需要设置一个max来保存最大值的情况,如果增加,则更新max的情况,否则不更新。


 

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值