动态规划专题—最大连续子序列和—A1007

最大连续子序列和问题如下

给定一个数字序列A1,A2,…,An,求i,j(1<=i<=j<=n),使得Ai+….+Aj最大,输出这个最大和。
样例:-2 11 -4 13 -5 2

1、令状态dp[i]表示以A[i]为结尾的连续序列的最大和,则dp[0] = -2,dp[1] = 11,dp[2] = 7,dp[3] = 20,dp[4] = 15,dp[5] = 13。
2、做如下考虑,因为dp[i]要求是必须以A[i]为结尾的连续序列,那么只有两种情况
a、最大和序列只有一个元素,即以A[i]开始,A[i]结尾
b、最大和序列有多个元素,且从前面A[p] (p

#include<cstdio>
#include<cstring>

void maxsublinear(int a[10010], int n)
{
    int i;
    int curSum = 0; /* 当前序列和 */
    int maxSum = 0; /* 最大序列和 */
    int begin = 0, end = 0;
    int out_begin = 0, out_end = 0;
    int allNegative = 1;
    /* 开始循环求子序列和 */
    for (i = 0; i < n; i++)
    {
        curSum = curSum + a[i];
        if(a[i] == 0 && allNegative)
        {   out_begin = i;
            out_end = i;
        }
        if(a[i]>=0) allNegative = 0;
        /* 与最大子序列和比较,更新最大子序列和 */
        if (curSum > maxSum)
        {
            maxSum = curSum;
            end = i;
            out_begin = begin;
            out_end = end;
        }

        /* 动态规划部分,舍弃当前和为负的子序列 */
        if (curSum < 0)
        {
            curSum = 0;
            begin = i + 1 >= n ? i : i + 1;
        }
    }
    //situation: all the numbers are negative
    if(allNegative)
    {   out_end = n-1;
        out_begin = 0;
    }
    printf("%d %d %d",maxSum,a[out_begin],a[out_end]);
}

int main()
{   int n;
    int seq[10010];
    scanf("%d",&n);
    for(int i = 0; i<n; i++)
        scanf("%d", &seq[i]);
    maxsublinear(seq, n);
    return 0;
}

猜你喜欢

转载自blog.csdn.net/daidaihema/article/details/79375632