Problem Description
给定一个由n个整数构成的数列A={a1,a2,...an},求出数列A中不相交的两个子段和,要求和最大。即计算如下定义的子段和函数d(A):
Input Description
可能会有多组测试数据,首先输入测试数据的组数m;
对于每组测试数据,输入有两行:第一行为整数的个数n; 第二行为n个整数。
Output Description
对于每组测试数据分行输出对应的子段和。
Sample Input
2
10
1 -1 2 2 3 -3 4 -4 5 -5
8
2 -2 4 4 -6 6 -7 7
Sample Output
13
15
#include<stdio.h>
int max_num(int a, int b)
{
if(a > b)
{
return a;
}
else
{
return b;
}
}
int main()
{
int n;
scanf("%d", &n);
for(int i = 0; i < n; i++)
{
int m;
scanf("%d", &m);
int a[m];
for(int j = 0; j < m; j++)
{
scanf("%d", &a[j]);
}
int left[m +1];
int right[m + 1];
int left_max[m + 1];
int right_max[m + 1];
for(int i = 0; i < m; i++)
{
left[i] = 0;
right[i] = 0;
left[i] = 0;
right_max[i] = 0;
}
left[0] = a[0];
for(int i = 1; i < m; i++)
{
if(left[i-1] < 0)
{
left[i] = a[i];
}
else
{
left[i] = left[i-1] + a[i];
}
}
left_max[0] = left[0];
for(int i = 1; i < m; i++)
{
left_max[i] = max_num(left_max[i - 1], left[i]);
}
right[m-1] = a[m-1];
for(int i = m - 2; i >= 0; i--)
{
if(right[i + 1] < 0)
{
right[i] = a[i];
}
else
{
right[i] = a[i] + right[i+1];
}
}
right_max[m -1] = right[m-1];
for(int j = m - 2; j >= 0; j--)
{
right_max[j] = max_num(right_max[j+1],right[j]);
}
int res = -1000000;
for(int i = 1; i < m; i++)
{
res = max_num(res, left_max[i-1]+right_max[i]);
}
printf("%d\n", res);
}
return 0;
}