题意:给定一个数列。求出数列中不相交的两个子段和,要求和最大
解题思路:对每一个i来说,求出[0-i-1]的最大子段和以及[i-n-1]的最大子段和,再加起来,求出最大的一个。[0-i-1]的最大子段和从左到右扫描。[i-n-1]从右到左扫描
#include<cstdio> #include<algorithm> using namespace std; const int MAXN = 50000; const int INF = 0x3ffffff; int a[MAXN + 5]; int left[MAXN + 5],right[MAXN + 5]; int main() { int count; scanf("%d",&count); while(count--) { int n; scanf("%d",&n); for(int i = 0;i<n;i++) scanf("%d",&a[i]); left[0] = a[0];//此时left[i]表示包含i在内左边的最大子段和 for(int i = 1;i<n;i++) { if(left[i-1]<0) left[i] = a[i]; else left[i] = a[i] + left[i-1]; } for(int i = 1;i<n;i++)//此时left[i]表示i左边的最大子段和 left[i] = max(left[i],left[i-1]); right[n-1] = a[n-1];//此时right[i]表示包含i在内右边的最大子段和 for(int i = n-2;i>=0;i--) { if(right[i+1]<0) right[i] = a[i]; else right[i] = a[i] + right[i+1]; } for(int i = n-2;i>=0;i--)//此时right[i]表示i右边的最大子段和 right[i] = max(right[i],right[i+1]); int num = -INF; for(int i = 1;i<n;i++)//求每一个i左边和右边的最大子段和相加,取最大值。 num = max(num,left[i-1]+right[i]); printf("%d",num); } return 0; }