POJ 2479 Maximum sum

来源:互联网 发布:龙族物语无法连接网络 编辑:程序博客网 时间:2024/04/30 15:47
Maximum sum
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 32910 Accepted: 10176

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.


思路:对于求数列中不相交的最大两个字段和,先从[0~i-1]的最大字段和从左向右扫描。[i~n-1]从右向左扫描即可

#include<cstdio>
#include<algorithm>
#define  MIN -0xffffff                 //直接转十进制数值是-16777215
using namespace std;


int a[100010];
int dp[100010];
int main()
{
  int n,t;
  scanf("%d",&t);
  while(t--)
  {
   scanf("%d",&n);
   int sum=0,count=MIN;
   for(int i=0;i<n;i++)
   {
      scanf("%d",&a[i]);
      sum+=a[i];                                 //输入时控制找出从左向右扫描的最大值; 
      if(sum>count)
          count=sum;  
      dp[i]=count;      
      if(sum<0)sum=0;      
   }        
   int S=MIN,m=0;
   count=MIN;
   for(int i=n-1;i>=1;i--)
   {
         m+=a[i];
         if(m>count)count=m;        //按照dp[n-2]是前n-1项的最大字段和,a[n-1]是最后一个数,
         if(m<0)m=0;       //dp[n-2]+a[n-1]相加与后面比较找出最大字段和,随后让dp[n-3]+count(a[n-2]与a[n-1]的最大字段和),后面同样,最终找出两个不相交最大字段和 
         if(count+dp[i-1]>S)S=count+dp[i-1];      
              
   }         
   printf("%d\n",S);                  
  }    
  system("pause");
  return 0;    
}


0 0