資訊學奧賽一本通:1305:Maximum sum
阿新 • • 發佈:2020-12-17
【題目描述】
對於給定的整數序列A={a1,a2,…,an},找出兩個不重合連續子段,使得兩子段中所有數字的和最大。我們如下定義函式 d(A):
d(A)=max1≤s1≤t1<s2≤t2≤n{}
我們的目標就是求出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
正向來一遍,算出開頭到當前元素之間的最大連續子段和;反著再來一遍,算出從當前元素開始至結尾的最大連續子段和。再正著來一遍,求兩者和的最大即可。
【AC程式碼】
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int INF=0x7fffffff;
const int N=50005;
int a[N],f[N],g[N],m[N];
int main()
{
int t,n,ans;
cin>>t;
while(t--)
{
cin>>n;
for(int i=1;i<=n;i++) cin>>a[i];
ans=-INF;
f[0]=g[n+1]=0;
for(int i=1;i<=n;i++)
{
f[i]=max(a[i],a[i]+f[i-1]);
ans=max(ans,f[i]);
m[i]=ans;
}
ans=-INF;
for(int i=n;i>0;i--)
{
g[i]=max(a[i],a[i]+g[i+1]);
ans=max(ans,m[i]+g[i+1]);
}
cout<< ans<<endl;
}
return 0;
}