01-复杂度2 Maximum Subsequence Sum

来源:互联网 发布:mac下载百度云太慢 编辑:程序博客网 时间:2024/05/03 10:54

原题描述:

Given a sequence of K integers { N1N2, ..., NK }. A continuous subsequence is defined to be { NiNi+1, ..., Nj } where 1. The Maximum Subsequence is the continuous subsequence which has the largest sum of its elements. For example, given sequence { -2, 11, -4, 13, -5, -2 }, its maximum subsequence is { 11, -4, 13 } with the largest sum being 20.

Now you are supposed to find the largest sum, together with the first and the last numbers of the maximum subsequence.

Input Specification:

Each input file contains one test case. Each case occupies two lines. The first line contains a positive integer K (). The second line contains K numbers, separated by a space.

Output Specification:

For each test case, output in one line the largest sum, together with the first and the last numbers of the maximum subsequence. The numbers must be separated by one space, but there must be no extra space at the end of a line. In case that the maximum subsequence is not unique, output the one with the smallest indices i and j(as shown by the sample case). If all the K numbers are negative, then its maximum sum is defined to be 0, and you are supposed to output the first and the last numbers of the whole sequence.

Sample Input:

10-10 1 2 3 4 -5 -23 3 7 -21

Sample Output:

10 1 4

这道题和第一题其实感觉差不多的。。。不过真的是来来回回改了无数回。。。

其实在已经明白如何求最大和值之后,最主要的点就是求最大和序列的第一个值和最后一个值,在各种情况下Last都是最容易找到的,问题就是如何找First.

if ( ThisSum > MaxSum )        {            count++ ;            MaxSum = ThisSum ;            Last = a[ i ] ;            First = a[ i - count + 1 ] ;        }

一开始的想法很简单,直接记录算进最大和的数值的个数,然后根据Last去找到First,但是错误项就出来了,如 1,2,3,-3,4,5,0 这种的序列(最大和序列含负数)在算进负数时,count的值是没有更新的,也就是说这个First值并不能单纯的依据这个count值来计算。

或者直接一点,返回去一个一个算呗。。。

    int tempSum = 0 ;    for ( i = Last ; i >= 0 ; i-- )    {        tempSum += a[ i ] ;        if ( tempSum == MaxSum )            break ;    }    First = i ;


其实仔细看看,First的值就是在ThisSum清零之后的那一个数值也就是此时的i+1

if ( ThisSum > MaxSum )        {            MaxSum = ThisSum ;            Last = i ;            First = s ;        }        if ( ThisSum < 0 )        {            ThisSum = 0 ;            s = i + 1 ;        }


把First 和Last 都当做数组下标来看之后,能够更好的弄清楚他们之间的关系。


其中的错误都是各种各样的,好在这个提交还会告诉我有哪些测试点,不然我怕是死都不知道为啥会有答案错误呵呵。还是太年轻。


其中测试点5 如 -1 -1 -1 0 0 这样由负数和0组成的序列,输出应该是0 0 0 而不是0 -1 0,First的值还是要根据序列的情况来做出改变(这个在序列情况中属于一种特例,所以直接在输出结果上更改就可以了)


每一个测试点都能让我更新一次代码,没办法漏洞太多,最后一个修改的漏洞也就是测试点6,最大和前面有一段是0,暂时还没有搞懂这到底是哪一种情况,

如果只是单纯的0 0 0 2 4 -5 这样的序列,输出结果应该为 6 0 4,而不是是6 2 4,可以直接更改判断MaxSum时的条件。

        if ( (ThisSum > MaxSum ) || ( ThisSum == MaxSum ) && ( MaxSum == 0 ))


满分提交代码:

#include <stdio.h>int main ( ){    int k , i , a [ 10000 ] ;    scanf("%d",&k );    for ( i = 0 ; i < k ; i ++ )        scanf("%d",&a[ i ] );    int MaxSum = 0 , ThisSum = 0 ,flag = 0 ;    int First = 0 , Last = k-1 , s = 0 ;    for ( i = 0 ; i < k ; i ++ )    {        ThisSum += a[ i ] ;        if ( a[ i ] >= 0 )            flag = 1 ;             //记录是否全为负数        if ( (ThisSum > MaxSum ) || ( ThisSum == MaxSum ) && ( MaxSum == 0 ))        {            MaxSum = ThisSum ;            Last = i ;            First = s ;        }        if ( ThisSum < 0 )        {            ThisSum = 0 ;            s = i + 1 ;        }    }/*     // 根据Last 找到First    int tempSum = 0 ;    for ( i = Last ; i >= 0 ; i-- )    {        tempSum += a[ i ] ;        if ( tempSum == MaxSum )            break ;    }    First = i ;*/    if ( MaxSum == 0 )    {        if ( flag == 1 )            printf("0 0 0\n");        else            printf("0 %d %d\n",a[ 0 ] , a[ k-1 ] );    }    else        printf("%d %d %d\n",MaxSum ,a[ First ] , a[ Last ] ) ;    return 0;}





原创粉丝点击