PAT甲级 1007 Maximum Subsequence Sum

Posted 晚风Serein

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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

以上是关于PAT甲级 1007 Maximum Subsequence Sum的主要内容,如果未能解决你的问题,请参考以下文章

PAT甲级 1007 Maximum Subsequence Sum

PAT甲级——A1007 Maximum Subsequence Sum

PAT甲级1007

甲级1007 Maximum Subsequence Sum

2019冬季PAT甲级第一题

[PTA] PAT(A) 1007 Maximum Subsequence Sum (25 分)