题意:
求一个数列内不相交的两个数列的最大和。
思路:
之前做过求最大子序列和的题目,利用dp。但是这道题目是两段不相交的数列,我们可以从前到后和从后到前进行两次dp,然后便可以求出他们的最大和。
dp关系式如下:
dp1[i] = max(dp1[i-1] + num[i],num[i]);//限制了num[i]一定参与,保证了数列的连续性
dp2[i] = max(dp2[i+1] + num[i],num[i]);
这里注意dp[i]的定义为包含第i个元素的最大数列和,所以在处理dp2的时候我们可以利用一个tmp维护最大子数列的值,也就是说可以在更新dp2的同时把两个数列的最大和求出。
代码实现:
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
using namespace std;
const int MAX = 50010;
const int INF = 0x7f7f7f7f;
int T;
int N;
int res;
int num[MAX];
int dp1[MAX];
int dp2[MAX];
int main()
{
scanf("%d",&T);
while( T-- ){
scanf("%d",&N);
for( int i = 0; i < N; i++ ){
dp1[i] = dp2[i] = -INF;
}
for( int i = 0; i < N; i++ ){
scanf("%d",&num[i]);
}
res = -INF;
dp1[0] = num[0];
dp2[N-1] = num[N-1];
for( int i = 1; i < N; i++ ){
dp1[i] = max(dp1[i-1]+num[i],num[i]);
}
int tmp = num[N-1];
for( int i = N-2; i >= 0; i-- ){
dp2[i] = max(dp2[i+1]+num[i],num[i]);
tmp = max(tmp,dp2[i+1]);
res = max(res,dp1[i]+tmp);
}
printf("%d\n",res);
}
return 0;
}