1. 程式人生 > 其它 >資訊學奧賽一本通:1305:Maximum sum

資訊學奧賽一本通:1305:Maximum sum

技術標籤:經驗動態規劃

【題目描述】
對於給定的整數序列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; }