题目:
A = {a1,a2...an}
函数D(A) = A1+A2;
A1 = {as1...at1}
A2 = {as2...at2}
1<=s1<=t1<=s2<=t2
例子:
A = {1 -1 2 2 3 -3 4 -4 5 -5}
在这个例子中,选择{2,2,3,-3,4} 和 {5},得到答案。
分析:
最大子序列和,时间复杂度为O(n)
int max = 0,current = 0;
for(int i=0;i<n;i++)
{
current+=a[i];
if(current>max)
max = current;
if(current<0)
current = 0;
}
改动一下得到,用数组储存左右两边的最大值,时间复杂度为O(n*ncase)
程序如下:
郁闷,没注意到Huge input,scanf is recommended.直接Time Limit Exceeded
#include <iostream>
#include <cstdio>
using namespace std;
#define X 50005
int Left[X]; //左边的最大值
int Right[X]; //右边的最大值
int a[X]; //输入的数据
int main()
{
freopen("sum.in","r",stdin);
freopen("sum.out","w",stdout);
int ncase,n;
cin>>ncase;
while(ncase--)
{
int max_left = -10001;
int max_right = -10001;
cin>>n;
for(int i=1;i<=n;i++)
scanf("%d",&a[i]);
int cur = 0;
for(int i=1;i<n;i++)
{ //求下标i前的的左边最大值
cur+=a[i];
if(cur>max_left)
max_left = cur;
if(cur<0)
cur = 0;
Left[i] = max_left;//把左边最大值付给该数组
}
cur = 0;
for(int i=n;i>1;i--)
{ //求下标i前的的右边最大值,要从最右开始算起
cur+=a[i];
if(cur>max_right)
max_right = cur;
if(cur<0)
cur = 0;
Right[i] = max_right; //把右边的最大值付给它
}
int max_total = -20001;
int temp;
for(int i=1;i<n;i++) //求最大值
{
temp = Left[i]+Right[i+1];
if(temp>max_total)
max_total = temp;
}
cout<<max_total<<endl;
}
return 0;
}