给定n个整数(可能为负数)组成的序列a[1],a[2],a[3],…,a[n],求该序列如a[i]+a[i+1]+…+a[j]的子段和的最大值。当所给的整数均为负数时,定义子段和为0。
要求算法的时间复杂度为O(n)。
输入格式:
输入有两行:
第一行是n值(1<=n<=10000);
第二行是n个整数。
输出格式:
输出最大子段和。
输入样例:
在这里给出一组输入。例如:
6
-2 11 -4 13 -5 -2
输出样例:
在这里给出相应的输出。例如:
20
解题:
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <string>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <list>
#include <sstream>
const int INF=0x3f3f3f3f;
typedef long long LL;
const int mod=1e9+7;
using namespace std;
#define ARR_SIZE 10001
int MaxSub(int a[],int left,int right);
int main(){
int n,a[ARR_SIZE],m,max;
scanf("%d",&n);
for(m=0;m<n;m++)
scanf("%d",&a[m]);
int b[100];
for(m=0;m<n;m++)
b[m+1]=a[m];
printf("%d",MaxSub(b,1,n));
}
int MaxSub(int a[],int left,int right){
int sum=0;
if(left==right)sum=a[left]>0?a[left]:0;
else{
int center=(left+right)/2;
int leftsum=MaxSub(a,left,center);
int rightsum=MaxSub(a,center+1,right);
int sum1=0;
int lsum=0;
for(int i=center;i>=left;i--){
lsum+=a[i];
if(lsum>sum1)sum1=lsum;
}
sum+=sum1;
sum1 = 0;
int rsum=0;
for(int i=center+1;i<=right;i++){
rsum+=a[i];
if(rsum>sum1)sum1=rsum;
}
sum+=sum1;
if(sum<leftsum)sum=leftsum;
if(sum<rightsum)sum=rightsum;
}
return sum;
}