HAUTOJ 1266 最大子段和

来源:互联网 发布:图片不停绕中心旋转js 编辑:程序博客网 时间:2024/05/27 20:43

题目链接:HAUTOJ 1266

方法一:根据最大连续子列和问题可以改编成每次加两个数,注意因为奇数长度需要有两个开始项,从第一个开始(奇数项开始),和从第二项开始(偶数项开始),还需要注意加a[i+1]时更新sum,即把a[i+2]作为第一项

方法二:加一个数列b,第一二项分别为a的一二项,从第三项开始b[i]=b[i-2]+a[i-1]+a[i],b[i]表示从第一项到当前项的奇数长度的和,如果b[i]<a[i]的话,表示前面为负值,更新开始项

方法一

#include<iostream>#include<algorithm>using namespace std;int main(){    int T;    cin>>T;    while(T--)    {        int a[100005],max1,max2,max0,i,j,k,n,sum;        cin>>n;        cin>>a[1];        max0=a[1];        for(i=2;i<=n;i++)        {            cin>>a[i];            if(a[i]>max0)max0=a[i];//寻找数组中最大元素         }        if(max0<0||n<3)        {        cout<<max0<<endl;        continue;        }                max1=a[1];//两种情况,一是从奇数列开始的最大奇数子列和,一是从偶数列开始         sum=a[1];        for(i=1;i+2<=n;i+=2)//每次加两个,保证奇数长度         {            sum+=a[i+1];//注意这地方加上第一个元素的时候不变成0              if(sum<0)sum=0;//这时候才变成0,保证奇数列             sum+=a[i+2];            if(sum>max1)max1=sum;//更新最大和         }                 max2=a[2];        sum=a[2];        for(i=2;i+2<=n;i+=2)        {            sum+=a[i+1];            if(sum<0)sum=0;            sum+=a[i+2];            if(sum>max2)max2=sum;        }                 max0=max(max1,max2);        cout<<max0<<endl;    }    return 0;}
方法二

#include <bits/stdc++.h>using namespace std;int a[100005],b[100005];int main(){int T;scanf("%d",&T);while(T--){int n;scanf("%d",&n);for(int i=0;i<n;i++){scanf("%d",&a[i]);}if(n==1){printf("%d\n",a[0]);}else if(n==2){printf("%d\n",max(a[0],a[1]));}else{b[0]=a[0],b[1]=a[1];//b[i]表示从第一项到当前项的奇数长度的和 int Max=max(a[0],b[0]);for(int i=2;i<n;i++){b[i]=max(a[i],b[i-2]+a[i-1]+a[i]);//每次加两个,如果为负值的话,a[i]更新为当前项,即第一项 if(b[i]>Max)//更新最大值 Max=b[i];}printf("%d\n",Max);}}}



1 0
原创粉丝点击