Max Sum

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 }
View Code

 

转载于:https://www.cnblogs.com/Wurq/articles/3894327.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值