题意,求序列中的两个子序列(不相交)使得相加的和最大
第一步:计算以i结尾的最大子序列和,从左往右。计算以i开始的最大子序列,从右往左
第二步:在第一步的基础上计算前0-i的最大子序列和O(n)扫描完成
第三步:枚举分界点O(n)时间
#include <iostream>
#include <vector>
#include <map>
#include <list>
#include <set>
#include <deque>
#include <stack>
#include <queue>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <cstdio>
#include <iomanip>
#include <cmath>
#include <cstdio>
#include <iostream>
#include <string>
#include <sstream>
#include <cstring>
#include <queue>
using namespace std;
///宏定义
const int INF = 10000000;
const int MAXN = 50010;
const int maxn = MAXN;
///全局变量 和 函数
int T;
int n;
int A[maxn];
int leftt[maxn];
int rightt[maxn];
int main()
{
///变量定义
int i, j;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(i = 0; i < n; i++)
scanf("%d", &A[i]);
leftt[0] = A[0];
for(i = 1; i < n; i++)
{
if(leftt[i - 1] < 0)
leftt[i] = A[i];
else
leftt[i] = leftt[i - 1] + A[i];
}
rightt[n - 1] = A[n - 1];
for(i = n - 2; i >= 0; i--)
{
if(rightt[i + 1] < 0)
rightt[i] = A[i];
else
rightt[i] = rightt[i + 1] + A[i];
}
//注意,改为存储0-i最大连续和,不一定以i结尾
for(i = 1; i < n; i++)
leftt[i] = max(leftt[i], leftt[i - 1]);
for(i = n - 2; i >= 0; i--)
rightt[i] = max(rightt[i], rightt[i + 1]);
//一次扫描
int ans = -INF;
for(i = 0; i < n - 1; i++)
{
ans = max(ans, leftt[i] + rightt[i + 1]);
}
printf("%d\n", ans);
}
///结束
return 0;
}