hdu1003 Max Sum【最大连续子序列之和】

题目链接:https://vjudge.net/problem/HDU-1003

题目大意:
给出一段序列,求出最大连续子序列之和,以及给出这段子序列的起点和终点。

解题思路:
最长连续子序列之和问题其实有很多种求解方式,这里是用时间复杂度为O(n)的动态规划来求解。

思路很清晰,用dp数组来表示前i项的最大连续子序列之和,如果dp[i-1]>=0的话,则dp[i]加上dp[i-1]能够使dp[i]增大;若dp[i-1]<0的话,则重新以dp[i]为起点,起点更新。

#include <cstdio>

int main()
{
    int t, n, i, j, cas = 0;
    scanf("%d", &t);
    while (t--)
    {
        int dp[100010];         //dp数组表示以i为终点的最大连续子序列之和
        scanf("%d", &n);
        for (i = 1; i <= n; i++)scanf("%d", &dp[i]);
        dp[0] = -1;
        int max = -0x3f3f3f3f;
        int s=1,start=1, e;
        for (i = 1; i <= n; i++)
        {
            if (dp[i - 1] >= 0)dp[i] = dp[i - 1] + dp[i];       //若dp[i-1]>=0,则第i个数直接在原基础上相加
            else s = i;              //否则的话,以第i个数为起点重新相加
            if (max < dp[i])
            {
                max = dp[i];
                e = i;               //记录下此时的终点
                start = s;          //记录下此时的起点,要注意不要将start与s混淆,s只是为每一段的起点,而start才是当前所遇到的连续子序列和最大的起点
            }
        }
        printf("Case %d:\n", ++cas);
        printf("%d %d %d\n", max, start, e);
        if (t)printf("\n");
    }
    return 0;
}

2018-04-30

猜你喜欢

转载自www.cnblogs.com/00isok/p/8973840.html