PAT甲级 1007 Maximum Subsequence Sum

原题链接

PAT甲级 1007 Maximum Subsequence Sum

题目大意

输入一个K个数的序列,找出一个子序列,该子序列的和是所有子序列中最大的,并输出最大子序列的和、第一个数、最后一个数。如果该序列全为负数,则输出最大和为0、该序列的第一个数和最后一个数。

解题思路

在输入K个数的序列时,生成一个和序列sum,sum[i]表示该序列前i个数的和。那么子序列(下标从a到b)的和就可以表示为 sum[b]-sum[a-1] ,要使该子序列的和最大,则sum[a-1]要最小,故定义一个变量min表示在b之前的最小的sum的下标,sum[b]-sum[min] 即以b为末尾时的子序列的最大和。

定义一个max_sum存放原序列的子序列的最大和,比较 max_sum 和 sum[b]-sum[min] ,判断是否需要更新max_sum,更新时应一并更新最大子序列的头数(num[min+1])和尾数(num[end])

判断是否需要更新最小的sum的下标

在这里插入图片描述如图所示,当end遍历到9时,min应该等于7,此时 sum[9]-sum[7] 就是以9为末尾的最大的子序列和,该子序列下标为从8到9。

示例代码

#include<iostream>
#include<bits/stdc++.h>
#include<string>
using namespace std;

int main(){
    int K, pos;
    int num[10001];//num为输入的序列(下标从1开始)
    int sum[10001];//sum[i]为num序列前i个数的和
    bool allNegetive = true;//序列全负标志

    sum[0] = 0;

    cin >> K;
    for(pos=1; pos<=K; pos++){
        cin >> num[pos];
        if(num[pos]>=0) allNegetive = false;
        sum[pos] = sum[pos-1] + num[pos];
    }
    int min = 0;// 下标end之前的前i个数的和最小的下标
    int max_sum = -1;   //最大序列的和
    int left_num, right_num;    //最大序列的头数和尾数
    for(int end=1; end<=K; end++){
        if(sum[end]-sum[min] > max_sum){//min+1到end的序列和更大,更新最大和与头数和尾数
            max_sum = sum[end]-sum[min];
            left_num = num[min+1];
            right_num = num[end];
        }
        if(sum[end] < sum[min]) min = end;  //当前的前end个数的序列和更小,更新序列和最小下标min
    }

    if(allNegetive) cout << "0 " << num[1] << " " << num[K];
    else            cout << max_sum << " " << left_num << " " << right_num; 

    return 0;
}

参考解说

https://www.bilibili.com/video/BV1Mt4y197kC?p=7

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晚风也很浪漫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值