mooc作业题:Maximum Subsequence Sum

Maximum Subsequence Sum

又是一道最大子列和问题,这次题目相比原版增加了一项,要把最大子列的第一项和最后一项也打印出来。

题目描述
Given a sequence of K integers { N​1, N​2​​ , …, ​K }. A continuous subsequence is defined to be { N​i​​ , ​i+1, …, N​j } 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

思路:
求子列和的部分不再赘述,可以参考我的另一篇文章最大子列和问题
记录最大子列的首项和末项,我们需要用变量first和last来存储。建议对一个随机的序列手动试一下,只有这样才会发现思路。
大致想法是,加上第i项后,如果sum<0时,first肯定不会是第i项,可能会是第i+1项,所以first应该等于i+1。如果sum > max,说明找到了一个最大值,我们就将这个序号定为last。
但是这样会出现一个问题,每当sum<0时first都会变成i+1,但是如果最大子列和已经得到,此时我们是不希望first发生改变的,所以引入一个临时的变量thisfirst来记录每次sum<0后的那一项。而first则放到sum>max的情况下,每当我得到一个新的max时,first = thisfirst。

#include <iostream>
using namespace std;
 
int main()
{
    int N;
    cin>>N;
    
    int arr[N];
    for(int j = 0; j < N; j++) //输入序列
        cin>>arr[j];

    bool flag = false; //全都为负数时flag时false
    for(int k = 0; k < N; k++)
    {
        if(arr[k] >= 0)
            flag = true;
    }

    int sum = 0, max = -1; //细节,max初始化为-1,这样应对只有负数和0的情况
    int first, last, thisfirst = 0; //thisfirst要初始化为0,这样应对只有一个正数的情况
    for(int i = 0; i < N; i++)
    {
        sum+=arr[i];
        if(sum < 0)
            {
                sum = 0;
                thisfirst = i+1;
            }
        else if(sum > max)
            {
                max = sum;
                last = i;
                first = thisfirst;
            }
    }
    if(flag == true)
        cout<<max<<" "<<arr[first]<<" "<<arr[last]<<endl;
    else
        cout<<0<<" "<<arr[0]<<" "<<arr[N-1]<<endl; //全都是负数的情况
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值