求两段不相交的子段和S1、S2,使得
S1+S2值最大。
这是一个典型的动态规划问题,首先正向遍历一遍求得1-i的
最大
子段和(注意不一定包含a[i]),然后在反向遍历一遍求得i-1的
最大
子段和,然后枚举划分点,求得最后的值。时间复杂度为O(n)。
#include <stdio.h>
#include <iostream>
#include <string.h>
using namespace std;
int dp[100001];
int s[100001];
int n,ans,temp,sum,k,i;
int main()
{
scanf("%d",&k);
for(;k>0;k--)
{
scanf("%d",&n);
memset(dp,0,sizeof(dp));
temp=0;sum=-0x7fffffff;
for(i=1;i<=n;i++)
{
scanf("%d",&s[i]);
temp+=s[i];
if(temp>sum)
sum=temp;
if(temp<0)
temp=0;
dp[i]=sum;
}
sum=ans=-0x7fffffff;
temp=0;
for( i=n;i>1;i--)
{
temp+=s[i];
if(temp>sum)
sum=temp;
if(dp[i-1]+sum>ans)
ans=sum+dp[i-1];
if(temp<0)
temp=0;
}
printf("%d\n",ans);
}
}