Max Sum
Time Limit : 2000/1000ms (Java/Other) Memory Limit : 65536/32768K (Java/Other)
Total Submission(s) : 25 Accepted Submission(s) : 15
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
2
5 6 -1 5 4 -7
7 0 6 -1 1 -6 7 -5
Sample Output
Case 1:
14 1 4
Case 2:
7 1 6
Author
Ignatius.L
题目大意:
给定一串连续的数字,求在这串连续的数字中,最大连续子串的的和,起始坐标从1开始。
解题思路:
状态表示:用Sign,Begin,End。分别表示:记录需要更新时候的起始坐标;更新最大值时,记录的起始坐标;更新最大值时,记录的终点坐标
状态转移方程:
NUM用来获取每次输入的值,Now记录已连续累加的值,Max记录最大的连续累加值,在给Max和Now赋初值后,每当输入一个数据的时,则比较Now是否大于0,小于的话,超过底线,大于的话,累加刚输入的数值。然后与最大值比较,当大于最大值的时候,才需要更新其起始坐标和终点坐标。反之,没有大于最大值的话,继续进行下一次操作。
Max=Max{Now+NUM,Max} 详情请见代码:
时间复杂度:O(n), 空间上可以使用在线算法,空间复杂度为O(1)。


1 #include<stdio.h> 2 int main() 3 { 4 int NUM,Now,MAX,Sign,Begin,End; 5 int T,N,i,j; 6 scanf("%d",&T); 7 for(j=1;j<=T;j++) 8 { 9 scanf("%d",&N); 10 Begin=End=Sign=1; /*设定其实坐标和终点坐标以及标记坐标的的初始位置,*/ 11 for(i=1;i<=N;i++) 12 { 13 scanf("%d",&NUM); 14 if(i==1) /*当输入第一个值的时候,初始已累加的值和最大值*/ 15 {Now=MAX=NUM;continue;} 16 if(Now<0) /*如果已经累加的值小于0的话,表示已累加的值已经超过底线,*/ 17 { /*继续累加则会使负增益,既之前累加的那些值都可以抛弃*/ 18 Now=NUM; /*更新为当前输入的值并且更新标记位置*/ 19 Sign=i; /*标记坐标是用来标记当已累加值超过底线,重新更新记录起始位置的坐标*/ 20 } 21 else /*反之,如果已累加的值仍然是个正数,即便是负数,在下一次累加也是可能回升的,*/ 22 Now+=NUM; /*所以可以继续累加上当然输入的值*/ 23 if(Now>MAX) /*判定已累加值是否大于最大值的话*/ 24 { 25 MAX=Now; /*需要更新最大值,其实坐标便是标记坐标*/ 26 Begin=Sign; /*其实坐标便替换为标记坐标的位置*/ 27 End=i; /*终点坐标即为当前坐标的位置*/ 28 } 29 } 30 printf("Case %d:\n",j); 31 printf("%d %d %d\n",MAX,Begin,End); 32 if(j!=T) 33 printf("\n"); 34 } 35 return 0; 36 }