题目链接
http://bailian.openjudge.cn/practice/2479/
用两次动态规划,否则超时
#include <iostream>
#include <cstdio>
using namespace std;
int T, N;
long long A[51000];
long long front_sum[51000], back_sum[51000];
long long rsum[51000];
int main()
{
scanf("%d", &T);
while(T--)
{
long long max_sum = -999999;
scanf("%d", &N);
for(int i=0;i<N;i++)
scanf("%lld", &A[i]);
//memset(front_sum, 0,sizeof(front_sum));
//memset(back_sum, 0, sizeof(back_sum));
if(N == 1) // 处理特殊情况
{
printf("%lld\n", A[0]);
continue;
}
// 计算点i及之前的前缀最大和
front_sum[0] = A[0];
for(int i=1;i<N;i++)
front_sum[i] = max(front_sum[i-1]+A[i], A[i]);
// 计算点i及之后的后缀最大和
back_sum[N-1] = A[N-1];
for(int i=N-2;i>=0;i--)
back_sum[i] = max(back_sum[i+1]+A[i], A[i]);
// 计算点i右侧连续点的最大值
rsum[N-1] = back_sum[N-1];
for(int i=N-2;i>=0;i--)
rsum[i] = max(back_sum[i], rsum[i+1]);
for(int i=0;i<N-1;i++)
{
long long _sum = front_sum[i] + rsum[i+1];
max_sum = max(_sum, max_sum);
}
printf("%lld\n", max_sum);
}
return 0;
}