给定n个整数(可能包含负数)组成的序列,求该序列子段和的最大值。
#include<stdio.h>
#include<string.h>
//常规思路,暴力求解
/*
int maxSum(int *arr,int n)
{
int i,j,k;
int sum=0,thisSum,besti,bestj;
//i,j分表代表起始位置和终止位置
for(i=0;i<n;i++)
{
for(j=i;j<n;j++)
{
thisSum=0;
for(k=i;k<=j;k++)
{
thisSum+=arr[k];
}
if (thisSum>sum)
{
sum=thisSum;
besti=i;
bestj=j;
}
}
}
return sum;
}
*/
/*
//改进算法,简化暴力
int maxSum(int *arr,int n)
{
int i,j;
int sum=0,thisSum,besti,bestj;
for(i=0;i<n;i++)
{
thisSum=0;
for(j=i;j<n;j++)
{
thisSum+=arr[j];
if (thisSum>sum)
{
sum=thisSum;
besti=i;
bestj=j;
}
}
}
return sum;
}
*/
/*
//分治法
int maxSum(int *arr, int left, int right)
{
int sum=0;
int center;
int i;
int leftSum, rightSum, s1,s2,lefts,rights;
if(left==right)
sum=arr[left]>0?arr[left]:0;
else{
center=(left+right)/2;
leftSum=maxSum(arr,left,center);
rightSum=maxSum(arr,center+1,right);
lefts=0;s1=0;
for(i=center;i>=left;i--)
{
lefts=lefts+arr[i];
if(lefts>s1)
s1=lefts;
}
rights=0;s2=0;
for(i=center+1;i<=right;i++)
{
rights=rights+arr[i];
if(rights>s2)
s2=rights;
}
sum=s1+s2;
if (sum<leftSum)
sum=leftSum;
if (sum<rightSum)
sum=rightSum;
}
return sum;
}
*/
//动态规划求解
//将以i下标为终点的最大子段和记为b[i],而在计算b[i]时,首先考虑b[i-1]的符号
//如果b[i-1]>0,则b[i]=b[i-1]+a[i];否则b[i]=a[i]
int maxSum(int *arr,int n)
{
int sum=arr[0],b=0;
int i;
for(i=0;i<n;i++)
{
if(b>0) //如果b[i-1]>0,则b[i]=b[i-1]+arr[i]
b+=arr[i];
else //如果b[i-1]<=0,则b[i]=arr[i]
b=arr[i];
if(b>sum)
sum=b;
}
return sum;
}
int main()
{
int i,n;
int *arr;
scanf("%d",&n);
arr=new int[n];
for(i=0;i<n;i++)
scanf("%d",&arr[i]);
printf("%d\n",maxSum(arr,n));
return 0;
}