Maximum sum
Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 36100   Accepted: 11213

Description

Given a set of n integers: A={a1, a2,..., an}, we define a function d(A) as below:

tex=d%28A%29%3D%5Cmax_%7B1%5Cleq+s_1%5Cleq+t_1%3Cs_2%5Cleq+t_2%5Cleq+n%7D%5Cleft%5C%7B%5Csum_%7Bi%3Ds_1%7D%5E%7Bt_1%7Da_i%2B%5Csum_%7Bj%3Ds_2%7D%5E%7Bt_2%7Da_j%5Cright%5C%7D&driver=1" alt="">

Your task is to calculate d(A).

Input

The input consists of T(<=30) test cases. The number of test cases (T) is given in the first line of the input. 

Each test case contains two lines. The first line is an integer n(2<=n<=50000). The second line contains n integers: a1, a2, ..., an. (|ai| <= 10000).There is an empty line after each case.

Output

Print exactly one line for each test case. The line should contain the integer d(A).

Sample Input

1

10
1 -1 2 2 3 -3 4 -4 5 -5

Sample Output

13

Hint

In the sample, we choose {2,2,3,-3,4} and {5}, then we can get the answer. 



Huge input,scanf is recommended.

1000ms。50000个数,所以每次处理的时间复杂度不能超过nlogn,否则会超时。所以要让最后扫描一次就能求出答案。

基本思路就是第一次遍历先定义2个数组,分别记录前i项和(含i)与后n-i+1项和(含i)。

第二次遍历再定义2个数组。分别记录以i为终点(含i)的最大子段和与以i为起点(含i)的最大子段和。

第三次遍历再定义2个数组,分别记录第i项(含i)的之前的最大子段和与第i项(含i)的之后的最大子段和。最后遍历一遍数组求出i之前(含i)子段和与i之后(不含i)子段和的最大值就可以。

#include<stack>
#include<queue>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#pragma commment(linker,"/STACK: 102400000 102400000")
#define lson a,b,l,mid,cur<<1
#define rson a,b,mid+1,r,cur<<1|1
using namespace std;
const double eps=1e-6;
const int MAXN=50050; int num[MAXN],n,prev[MAXN],afte[MAXN],ans1[MAXN],ans2[MAXN],fans1[MAXN],fans2[MAXN],sum; int main()
{
#ifndef ONLINE_JUDGE
freopen("in.txt","r",stdin);
#endif // ONLINE_JUDGE
int tcase;
scanf("%d",&tcase);
while(tcase--)
{
scanf("%d",&n);
memset(prev,0,sizeof(prev));//前i项和(含i)
memset(afte,0,sizeof(afte));//后n-i+1项和(含i)
memset(ans1,0,sizeof(ans1));//以i为终点(含i)的最大子段和
memset(ans2,0,sizeof(ans2));//以i为起点(含i)的最大子段和
memset(fans1,0,sizeof(fans1));//第i项(含i)的之前的最大子段和
memset(fans2,0,sizeof(fans2));//第i项(含i)的之后的最大子段和
sum=0;
for(int i=1;i<=n;i++)
{
scanf("%d",&num[i]);
prev[i]=prev[i-1]+num[i];
sum+=num[i];
}
if(n==2)
{
printf("%d\n",sum);
continue;
}
for(int i=n;i>=1;i--)
afte[i]=afte[i+1]+num[i];
int minn=0;
for(int i=0;i<n;i++)
{
minn=min(prev[i],minn);
ans1[i+1]=prev[i+1]-minn;
//printf("%d\n",ans1[i+1]);
}
minn=0;
for(int i=n+1;i>0;i--)
{
minn=min(afte[i],minn);
ans2[i-1]=afte[i-1]-minn;
//printf("%d\n",ans2[i-1]);
}
int maxx=-99999999;
for(int i=1;i<=n;i++)
{
maxx=max(maxx,ans1[i]);
fans1[i]=maxx;
}
maxx=-99999999;
for(int i=n;i>=1;i--)
{
maxx=max(maxx,ans2[i]);
fans2[i]=maxx;
}
int ans=-99999999;
for(int i=1;i<n;i++)
ans=max(ans,fans1[i]+fans2[i+1]);//题目规定区间不能有交集
printf("%d\n",ans);
}
return 0;
}

POJ 2479 Maximum sum(双向DP)的更多相关文章

  1. (线性dp 最大连续和)POJ 2479 Maximum sum

    Maximum sum Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 44459   Accepted: 13794 Des ...

  2. POJ 2479 Maximum sum 解题报告

    Maximum sum Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 40596   Accepted: 12663 Des ...

  3. POJ #2479 - Maximum sum

    Hi, I'm back. This is a realy classic DP problem to code. 1. You have to be crystal clear about what ...

  4. poj 2479 Maximum sum (最大字段和的变形)

    题目链接:http://poj.org/problem?id=2479 #include<cstdio> #include<cstring> #include<iostr ...

  5. POJ 2479 Maximum sum POJ 2593 Max Sequence

    d(A) = max{sum(a[s1]..a[t1]) + sum(a[s2]..a[t2]) | 1<=s1<=t1<s2<=t2<=n} 即求两个子序列和的和的最大 ...

  6. [poj 2479] Maximum sum -- 转载

    转自 CSND 想看更多的解题报告: http://blog.csdn.net/wangjian8006/article/details/7870410                         ...

  7. poj 2479 Maximum sum(递推)

     题意:给定n个数,求两段连续不重叠子段的最大和. 思路非常easy.把原串划为两段.求两段的连续最大子串和之和,这里要先预处理一下,用lmax数组表示1到i的最大连续子串和,用rmax数组表示n ...

  8. URAL 1146 Maximum Sum(DP)

    Given a 2-dimensional array of positive and negative integers, find the sub-rectangle with the large ...

  9. POJ 1836 Alignment (双向DP)

    Alignment Time Limit: 1000MS   Memory Limit: 30000K Total Submissions: 10804   Accepted: 3464 Descri ...

随机推荐

  1. C#写的一个视频转换解码器

    C#写的一个视频转换解码器 using System; using System.Collections.Generic; using System.Linq; using System.Text; ...

  2. PostgreSQL学习资料

    我的PostgreSQL学习笔记:http://note.youdao.com/share/?id=2e882717fc3850be9af503fcc0dfe7d0&type=notebook ...

  3. ios app在itunesConnect里面的几种状态

    原地址:http://blog.csdn.net/dean19900504/article/details/8164734 Waiting for Upload (Yellow) Appears wh ...

  4. C语言-gdb调试工具详解

    回车 重复上一次命令 产生可调试的可执行文件:gcc -g main.c -o main, 必须加上-g选线, 表示在可执行文件中加入源文件信息, 但并不是将源文件嵌入可执行文件, 所以在调试时必须保 ...

  5. HDU 4421 Bit Magic(2-sat)

    HDU 4421 Bit Magic pid=4421" target="_blank" style="">题目链接 题意:就依据题目,给定b数 ...

  6. centos/rhel下实现nginx自启动脚本实例

    1. 建立脚本文件nginxd [root@could]# vi /etc/init.d/nginxd 插入以下内容   #!/bin/bash # # chkconfig: - 85 15 # de ...

  7. sqlite or svn 错误 The database disk image is malformed 可解决

    在网上找了很多资料,很多网友都提到这个问题是不可解决的,面对这个问题,只能作罢. 但我不甘心这么丢失数据,最最后找到了一个解决方法.经测试,原来数据,全部保住. 以下为原文. http://www.s ...

  8. url传递参数

    url:'/randowCode?t='+Math.random(); //当给某个赋值可以: $('#change').click(function(){ $("#codeimage&qu ...

  9. java的大端小端和c#如何对应

    当前的存储器,多以byte为访问的最小单元,当一个逻辑上的地址必须分割为物理上的若干单元时就存在了先放谁后放谁的问题,于是端(endian)的问题应运而生了,对于不同的存储方法,就有大端(big-en ...

  10. keypad代码分析

    keypad作为input设备注册到内核,与platform总线驱动match. 1.描述一个输入设备对象 static struct input_dev *kpd_input_dev; 告知输入子系 ...