PAT (Advanced Level) Practice 1007 Maximum Subsequence Sum

Given a sequence of K integers { N1, N2, …, NK}. A continuous subsequence is defined to be { Ni, Ni+1, …, Nj} where 1≤i≤j≤K. 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 (≤10000). 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

题目大意

给出一个长度为 K (≤10000)的数列,求子序列的最大和,子序列指从原序列的第 i 个到第 j 个之间所有的数字组成的序列(1≤i≤j≤K)。输出子序列最大和,以及该子序列的第一个数字和最后一个数字。如果有多个子序列的和都是最大的,则以 i 和 j 为最小的那个为准。
如果原序列所有数字都是负数,则将最大和定义为0,输出整个数列的第一个数字和最后一个数字。

题目分析

设num[x]表示第x个数字,sum[x]表示前x个数字的和,0 <= x < K。在输入数据时维护sum数组。从 i 到 j 的子序列的和为 sum[j] – sum[i] + num[i],因此从小到大枚举 i 和 j 即可找出最大值 ans。
值得注意的是,当原数列中最大的数为 0 时,结果为 0 0 0,因此序列和的最大值 ans 需要初始化为小于 0 的数,才能正确得到结果。

AC代码

#include <bits/stdc++.h>
using namespace std;
int num[10005], sum[10005] = {0};
int main()
{
    int k, i, j, flag = 0, ans = -1, ans1, ans2;
    cin >> k >> num[0];
    sum[0] = num[0];
    for (i = 1; i < k; i++)
    {
        cin >> num[i];
        sum[i] = num[i] + sum[i - 1];
        if (num[i] >= 0)
            flag = 1;
    }
    if (flag == 0 && num[0] < 0)
    {
        printf("%d %d %d\n", 0, num[0], num[k - 1]);
        return 0;
    }
    for (i = 0; i < k; i++)
    {
        for (j = i; j < k; j++)
        {
            if (sum[j] - sum[i] + num[i] > ans)
            {
                ans = sum[j] - sum[i] + num[i];
                ans1 = num[i], ans2 = num[j];
            }
        }
    }
    printf("%d %d %d\n", ans, ans1, ans2);
    return 0;
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

开始在上面输入您的搜索词,然后按回车进行搜索。按ESC取消。

返回顶部