PAT甲级_1007(Maximum Subsequence Sum)

1007 最大子序列和

给定一个包含K个整数的序列{N1,N2,…,NK}。定义连续子序列为{Ni,Ni+1,…,Nj},且(1 <= i <= j <= K)。最大子序列是具有最大元素和的连续子序列。例如:序列{-2,11, -4,13,-5,-2}的最大子序列是{11,-4,13},最大和是20。现在,你应该找到最大和,以及最大子序列的第一个元素和最后一个元素。

输入规范

每个输入文件包含一个测试用例。每个测试用例占两行。第一行包含一个正整数K(K<=10000)。第二行包含K个用空格分离的数字。

输出规范

对于一个测试用例,在一行输出最大和,以及最大子序列的第一个元素值和最后一个元素值。这些数字用空格分隔,但是行末尾元素后不应加空格。当最大子序列不唯一时,输出索引最小的i和j(如案例所示)。如果K个数字都是负数,我们定义最大和为0,你应该输出序列的第一个和最后一个数。

输入样例
10
-10 1 2 3 4 -5 -23 3 7 -21
输出样例
10 1 4
AC代码
#include 
#include 
using namespace std;
const int MAXN = 10005;
const int INF = 0x3f3f3f3f;
int value[MAXN];
int main() {
    int n; 
    cin >> n;
    bool sign = true;   //记录是否有正数,如果有,则为false
    for(int i = 0; i < n; i++) {
        cin >> value[i];
        if(value[i] >= 0) {
            sign = false;
        }
    }
    
    if(sign) {  //特殊情况,K个数字全为负数
       cout << 0 << ' ' << value[0] << ' ' << value[n-1] << endl;
    }else {
        int max_sum = -INF;     //最大子序列和
        int start = 0, end = 0; //子序列的开始和结束位置索引
        int sum = 0;
        for(int i = 0, t = 0; i < n; i++) {     //t保存当前计算的序列的开始位置
            sum += value[i];    
            if(max_sum < sum) { //如果当前子序列和大于以前计算的子序列和,则更新答案
                max_sum = sum;
                start = t;
                end = i;
            }   
            if(sum < 0) {       //如果当前子序列和小于0,则下一个计算的子序列不可能接在当前子序列后面(负数+X < X)
                sum = 0;
                t = i+1;
            }
        }
        cout << max_sum << ' ' << value[start] << ' ' << value[end] << endl;
    }
    return 0;
}

你可能感兴趣的:(PAT甲级)