HDU--Max Sum

来源:互联网 发布:java手机 微信 不能用 编辑:程序博客网 时间:2024/05/19 20:21

Max Sum

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 131345    Accepted Submission(s): 30431


Problem Description
Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14.
 

Input
The first line of the input contains an integer T(1<=T<=20) which means the number of test cases. Then T lines follow, each line starts with a number N(1<=N<=100000), then N integers followed(all the integers are between -1000 and 1000).
 

Output
For each test case, you should output two lines. The first line is "Case #:", # means the number of the test case. The second line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the first one. Output a blank line between two cases.
 

Sample Input
25 6 -1 5 4 -77 0 6 -1 1 -6 7 -5
 

Sample Output
Case 1:14 1 4Case 2:7 1 6
解析:
对于整个序列a[n]来说,它的所有子序列有很多很多,但是可以将它们归类。
注意,是以**结尾的子序列,其中肯定是要包含**的了
以a[0]结尾的子序列只有a[0]
以a[1]结尾的子序列有 a[0]a[1]和a[1]
以a[2]结尾的子序列有 a[0]a[1]a[2] / a[1]a[2] / a[2]
……
以a[i]结尾的子序列有a[0]a[1]……a[i-2]a[i-1]a[i]  / a[1]a[2]……a[i-2]a[i-1]a[i] /  a[2]a[3]……a[i-2]a[i-1]a[i] / …… /  a[i-1]a[i] / a[i]
所有以a[0] ~a[n]结尾的子序列分组构成了整个序列的所有子序列。

这样,我们只需求以a[0]~a[n]结尾的这些分组的子序列中的每一分组的最大子序列和。然后从n个分组最大子序列和中选出整个序列的最大子序列和。
观察可以发现,0,1,2,……,n结尾的分组中,
maxsum a[0] = a[0]
maxsum a[1] = max( a[0] + a[1] ,a[1])  = max( maxsum a[0] + a[1] ,a[1]) 
maxsum a[2] = max( max ( a[0] + a[1] + a[2],a[1] + a[2] ),a[2])  
= max(  max( a[0] + a[1] ,a[1]) + a[2] , a[2]) 
= max(  maxsum a[1] + a[2] , a[2])
……
依此类推,可以得出通用的式子。
maxsum a[i] = max( maxsum a[i-1] + a[i],a[i])
#include <iostream>  using namespace std;  int main()  {      int j,i,k,n,m,t;      int a;  //不需要数组,只需要一个输入变量    scanf("%d",&t);      for (j=1;j<=t;j++)      {          scanf("%d",&n);          int sum=0,maxsum=-1001,first =0, last = 0, temp = 1;          for (i=0;i<n;i++)          {              scanf("%d",&a);             sum += a;              if (sum > maxsum)              {                  maxsum = sum;first = temp;last = i+1;              }              if (sum < 0)              {                  sum = 0;temp = i+2;              }          }    //注意格式,我就因为将冒号写到了数的前边而wrong answer,郁闷半天才发现……        printf("Case %d:\n%d %d %d\n",j,maxsum,first,last);          if (j!=t)          {              printf("\n");          }      }      return 0;  } 
0 0
原创粉丝点击