POJ 2479 Maximum sum dp

来源:互联网 发布:上海房价还会涨吗 知乎 编辑:程序博客网 时间:2024/06/05 19:57

Maximum sum
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 39194 Accepted: 12260

Description

Given a set of n integers: A={a1, a2,..., an}, we define a function d(A) as below:
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

1101 -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.

Source

POJ Contest,Author:Mathematica@ZSU

    题意:找出两个连续的没有交集的子序列,使得它们的和最大。

    分析:转化为求解最大和问题。一般的使用dp求解最大连续序列和问题中,dp[i]指的是以i末尾元素的最大子序列的和,但该题要求的是该点左侧的连续序列中,最大的连续区间和,所以判断写法需要稍作改变求出以第一个元素为起点,该元素为右侧区间的区间内最大的连续序列区间和,同样可以求出以该点为左侧第一个元素,最后一个元素为右侧区间的区间上的最大连续区间和,因为区间是不能相交的,所以可以遍历i为0至n-2元素,以他们作为左侧区间的右侧端点,相应的i+1右侧即为右侧区间最大值,即i+1到n-1区间上的最大值,遍历后可以得到最大的值。可以做出优化,即不使用数组保存右边数组的值,在遍历过程中可以直接比较生成最终的结果。需要注意的是,使用max函数时,初始的res值需要赋值为无穷小,因为该题的数据含有负数,因为此原因初始时候wa了一次。其他详见AC代码:

#include<stdio.h>#include<algorithm>using namespace std;const int maxn= 50005;long long  a[maxn],r[maxn];//r[i]以i为最后一个数的左侧区间的最大值 int main(){int T;scanf("%d",&T);while(T--){int n;scanf("%d",&n);for(int i=0; i<n; i++)scanf("%lld",&a[i]);long long sum=0,res=-0x3f3f3f3f; //注意res不能初始为0 防止有负数 for(int i=0; i<n; i++){sum+=a[i];//加上一个数后 值是否变小 if(sum>res) //变大的时候更新 res=sum;//res保存最大的值 r[i]=res;if(sum<0)//如果最大值小于0  则初始为0 sum=0;}sum=0,res=-0x3f3f3f3f;long long ans=-0x3f3f3f3f;for(int i=n-1; i>=1; i--)//以n-1为下标 为右半区间  逐次加上它左半区间的最大值 {sum+=a[i];if(sum>res)res=sum;ans=max(r[i-1]+res,ans);//注意使用max时  初始元素的赋值 if(sum<0)sum=0;}printf("%lld\n",ans);}}
    特记下,以备后日回顾。

1 0
原创粉丝点击