注意问题的转化
第一次DP是求以i结尾的最大子串和
然后遍历一遍就知道了到i为止的最大子串和(不必包括i)
然后正反求两次上面讲的过程
正反两次的结果挨着的两个值相加就是和了。然后求个最大值就行了
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;
int main()
{
int num = 0;
int n = 0;
int a[50000];
int d[50000];
int e[50000];
memset(a,0,sizeof(a));
memset(d,0,sizeof(d));
memset(e,0,sizeof(e));
scanf("%d", &num);
int i = 0;
int j = 0;
int k = 0;
for (i = 0; i < num; i++) {
scanf("%d", &n);
for (j = 0; j < n; j++) {
// printf("%d",j);
scanf("%d", &a[j]);
if (j == 0) d[j] = a[j]>0?a[j]:a[j];
else {
d[j] = max(d[j-1] + a[j], a[j]); // find max valued end with i
}
}
for (j = 1;j < n; j++) {
d[j] = d[j]<d[j-1]?d[j-1]:d[j]; // find max valued between 0 and i(unnecessary end with i)
}
e[n-1] = a[n-1]>0?a[n-1]:a[n-1];
for (j = n-2; j >= 0; j--) {
e[j] = max(e[j+1] + a[j], a[j]);
}
for (j = n-2; j >= 0; j--)
e[j] = e[j]<e[j+1]?e[j+1]:e[j];
int mymax = d[0]+e[1];
for (k = 0; k < n - 2; k++) {
int tmp = d[k]+e[k+1];
mymax = mymax<tmp?tmp:mymax;
}
printf("%d\n",mymax);
}
}