zoukankan      html  css  js  c++  java
  • ACM学习历程—HDU1003 Max Sum(dp && 最大子序列和)

    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
     

    这是一道求最大子序列和的题。

    思路就是考虑到对于S(i...k) + S(k+1...j) = S(i...j),如果S(i...k)小于0,自然考虑S(k+1...j)这段和;反之,考虑S(i...j)。

    于是从1到n,判断当前的S(i...k)是否小于0,大于0则保留,否则舍去。

    考虑到可能整个过程可能S(i...k)一直小于0,所以即使小于0,也要保留当前值now,将其与ans比较。

    代码:

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <cmath>
    #include <algorithm>
    #include <set>
    #include <map>
    #include <vector>
    
    using namespace std;
    
    int n;
    int ans, from, to;
    
    void Work()
    {
        from = -1;
        to = -1;
        int k, now, u = -1, v = -1;
        scanf("%d", &n);
        for (int i = 1; i <= n; ++i)
        {
            scanf("%d", &k);
            if (u == -1 || now < 0 || now+k < 0)
            {
                u = v = i;
                now = k;
            }
            else
            {
                v = i;
                now = now+k;
            }
            if (from == -1 || now > ans)
            {
                ans = now;
                from = u;
                to = v;
            }
        }
    }
    
    int main()
    {
        //freopen("test.in", "r", stdin);
        int T;
        scanf("%d", &T);
        for (int times = 1; times <= T; ++times)
        {
            Work();
            if (times != 1)
                printf("
    ");
            printf("Case %d:
    ", times);
            printf("%d %d %d
    ", ans, from, to);
        }
        return 0;
    }
    
  • 相关阅读:
    1082 射击比赛 (20 分)
    1091 N-自守数 (15 分)
    1064 朋友数 (20 分)
    1031 查验身份证 (15 分)
    1028 人口普查 (20 分)
    1059 C语言竞赛 (20 分)
    1083 是否存在相等的差 (20 分)
    1077 互评成绩计算 (20 分)
    792. 高精度减法
    791. 高精度加法
  • 原文地址:https://www.cnblogs.com/andyqsmart/p/4498127.html
Copyright © 2011-2022 走看看