在输入的同时,进行一次DP,计算出从左到右的最大值,并把它保存在数组dp的对应的下标元素中,这样之后,对于下标为i的元素,它其中保存的便是前面所有元素可能的最大连续和。再从右到左进行一次DP,计算从右到左的最大连续和。假设此时已经算到下标为i的元素,那么将sum+dp[i-1]与ans进 行比较,将ans取较大者。最后当i到2的时候ans中的值即为所求的最大值。
#include<stdio.h>
#include<stdlib.h>
#include<iostream>
using namespace std;
const int inf=-0x3f3f3f3f;
int main()
{
int T=0,n=0,i=0,temp=0,sum=0,ans=0,Arr[50005]={0},dp[50005]={0};
scanf("%d",&T);
while(T--)
{
scanf("%d",&n);
temp=inf;
sum=0;
ans=0;
for(i=1;i<=n;i++)
{
scanf("%d",&Arr[i]);
///从左到右求最大子串和
sum+=Arr[i];
if(sum>temp)
temp=sum;
dp[i]=temp;
if(sum<0)
sum=0;
}
///再从右往左找右边的子串和与左边子串和的最大值
temp=ans=inf;
sum=0;
for(i=n;i>1;i--)///肯定是只能到i=2;因为还要俩个子串呢
{
sum+=Arr[i];
if(sum>temp)
temp=sum;
if(ans<dp[i-1]+temp)
ans=dp[i-1]+temp;
if(sum<0)
sum=0;
}
printf("%d\n",ans);
}
return 0;
}