题意:
题意很简单,给n个数,求出两个无交叉的两段和最大,输出和。
思路:
一般会想到,求两次子串,但是问题是这样会出现重合的现象。
所以按照书上的方法是不合适的,所以需要另寻方法。问题是左串+右串,可不可> 以先把一种情况全部求出?可以的,比如把左边的每个最大串的和保存到一个数
组里面,然后再想办法找出右串,所以此时找到右串比较好的方法是用相同的方法从右边遍历,然后找到右串与之前保存的左串进行比较,由于比较的是左串[i-1]的情况所以不会有交叉。
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
int a[50005],lef[50005];
int main()
{
//freopen("in.txt","r",stdin);
int t;
scanf("%d",&t);
while(t--) {
int n;
scanf("%d",&n);
int M = -INF,sum = 0;
for(int i = 1;i <= n; i++) {
scanf("%d",&a[i]);
sum += a[i];
if(sum > M)
M = sum;
lef[i] = M; //保存的左串表示第1~i个最大的串之和
if(sum < 0) //注意负数的情况一定要为0,因为负数相加会更小
sum = 0;
}
M = -INF,sum = 0;
int ans = -INF;
for(int i = n;i > 1; i--) { //从右边找右串
sum += a[i];
if(sum > M)
M = sum;
if(ans < M + lef[i-1]) { //这里是所求的右串加左串的情况
ans = M + lef[i-1];
//printf("%d\n",i);
}
if(sum < 0)
sum = 0;
}
printf("%d\n",ans);
}
return 0;
}