【題目描述】
對於給定的整數序列A={a1,a2,...,an},找出兩個不重合連續子段,使得兩子段中所有數字的和最大。我們如下定義函數 d(A):
d(A)=max1≤s1≤t1≤s2≤t2≤n{∑i=s1t1ai+∑j=s2t2aj}
我們的目標就是求出d(A)。
【輸入】
第一行是一個整數T(≤30),代表一共有多少組數據。
接下來是T組數據。
每組數據的第一行是一個整數,代表數據個數據n(2≤n≤50000),第二行是n個整a1,a2,...,an(|ai|≤10000)
。
【輸出】
輸出一個整數,就是d(A)的值。
【輸入樣例】
1
10
1 -1 2 2 3 -3 4 -4 5 -5
【輸出樣例】
13
【提示】
就是求最大子段和問題,樣列取2,2,3,−3,4
和5,Baidu搜POJ 2479 Maximum sum,可獲得大量經典最大子段和問題的題目解析,本題O(n2)算法超時,必須用O(n)算法。
//Created on 2020/2/22
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const int idata=50000+5;
int dpleft[idata];
int dpright[idata];
int temp[idata];
int step[idata];
int m,n,x,y,t;
int i,j,k;
int ACans;
void initial()
{
for(i=1;i<=n;i++)
cin>>step[i];
memset(temp,0,sizeof(temp));
memset(dpleft,0,sizeof(dpleft));
memset(dpright,0,sizeof(dpright));
return ;
}
int main()
{
cin>>t;
while(t--)
{
cin>>n;
initial();
ACans=-inf;
for(i=1;i<=n;i++)
{
dpleft[i]=max(dpleft[i-1]+step[i],step[i]);
//從前尋找最大序列和
ACans=max(ACans,dpleft[i]);
temp[i]=ACans;
//到i位置最大序列和
}
ACans=-inf;
for(i=n;i>=1;i--)
{
dpright[i]=max(dpright[i+1]+step[i],step[i]);
//從後向前最大序列和
ACans=max(ACans,temp[i-1]+dpright[i]);
}
cout<<ACans<<endl;
}
return 0;
}