POJ 2479:Maximum sum(贪心)

http://poj.org/problem?id=2479

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

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.

题意分析:

找出两个不重合的区间,使区间中的值相加最大。

解题思路:

 dp1[i] 代表从 1 到 i 区间中能取到的最大值, dp2[i] 代表从 i 到 n 区间中能取到的最大值,那么

dp1[ i ] + dp2[ i + 1 ] 代表,前一区间是1到 i, 后一区间是i+1 到n,能取到的最大值,

再遍历i找出最大的值。

#include <stdio.h>
#include <algorithm>
#define N 50050
using namespace std;
int a[N], dp1[N], dp2[N], sum, ans;

int main()
{
	int T, n, i, count, min1, min2;
	scanf("%d", &T);
	while(T--)
	{
		scanf("%d", &n);
		count=0;
		min1=min2=-99999999;
		for(i=1; i<=n; i++)
		{
			scanf("%d", &a[i]);
			if(a[i]>=0)
				count++;
			else{
				if(a[i]>min1)
				{
					min2=min1;
					min1=a[i];
				}
				else if(a[i]>min2)
					min2=a[i];
			}	
		}
		if(count==0)
		{
			printf("%d\n", min1+min2);
			continue;
		}	
		sum=0;
		for(i=1; i<=n; i++)
		{
			sum+=a[i];
			if(sum<0)
				sum=0;
			dp1[i]=max(dp1[i-1], sum);
		}
		dp2[n+1]=0;
		sum=0;
		for(i=n; i>0; i--)
		{
			sum+=a[i];
			if(sum<0)
				sum=0;
			dp2[i]=max(dp2[i+1], sum);
		}
		ans=0;
		for(i=1; i<=n; i++)
		{
		//	printf("%d %d\n", dp1[i], dp2[i+1]);
			ans=max(ans, dp1[i]+dp2[i+1]);
		}
		if(count==1)
			printf("%d\n", ans+min1); 
		else
			printf("%d\n", ans);
	}
	return 0;
}

 

posted @ 2019-08-08 09:28  宿星  阅读(140)  评论(0编辑  收藏  举报