<p>//题目:<a target=_blank href="http://poj.org/problem?id=2479">http://poj.org/problem?id=2479</a></p><p></p><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; font-size: 14px; line-height: 26px;">//题意:</p><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-family: Arial; font-size: 14px; line-height: 26px;">// <span style="font-family: SimSun;"> 题目的大概意思是把数组分成不交两段,分别求出两段的最大子段和s1和s2,然后求出最大的s1+s2。</span></p><p style="margin-top: 0px; margin-bottom: 0px; padding-top: 0px; padding-bottom: 0px; font-size: 14px; line-height: 26px;"><span style="font-family: SimSun;">//这种问题往往感觉像字符串问题,所以记下来,经常会用</span></p>
#include <iostream>
#include <iomanip>
#include <fstream>
#include <sstream>
#include <algorithm>
#include <string>
#include <set>
#include <Map>
#include <utility>
#include <queue>
#include <stack>
#include <list>
#include <vector>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
using namespace std;
const int maxn = 50005;
int left1[maxn]; //left1和right1分别记从哪个方向来的最大数
int right1[maxn];
int a[maxn];
int main()
{
int t, n;
scanf("%d", &t);
while (t--)
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
}
left1[1] = a[1];
for (int i = 2; i <= n; i++) //left从左往右加的时候,一旦前面的和为负,后边就另起炉灶记最大数
{
if (left1[i-1] > 0)
left1[i] = left1[i-1] + a[i];
else
left1[i] = a[i];
}
for (int i = 2; i <= n; i++) //最大之和肯定是第i个或者第i-1个
left1[i] = max(left1[i], left1[i-1]);
right1[n] = a[n];
for (int i =n-1;i>=1;i--){
if(right1[i+1] > 0){
right1[i] = right1[i+1] +a[i];
}
else
right1[i] = a[i];
}
for(int i =n-1;i>=1;i--)
right1[i] = max(right1[i],right1[i+1]);
int ans = left1[1] + right1[2];
for (int i = 2; i < n; i++)
{
ans = max(left1[i]+right1[i+1], ans);
}
printf("%d\n", ans);
}
return 0;
}