1305:Maximum sum

【題目描述】

對於給定的整數序列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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章