PAT甲级 A1007 Maximum Subsequence Sum
随手记录,只希望能帮助到同样遇到问题的小伙伴呀~
还是学生,水平有限,写的不好的地方有请指正~
最大子序列和,核心思想就是从头往后遍历,如果之前的和小于0,那就重新开始这个子序列(因为前面的值是负的,那与后面的相加肯定是更小的,为了尽可能大,舍弃前面的序列),然后每次都和目前最大的和比较并记录最大值以及子序列的开头值与结尾值。
我踩的坑是,读题读错了,一开始以为是子序列的开头下标与结尾下标(正好给的例子也是匹配的),结果只过了一个测试点。
其余的就是满足这题的其他奇奇怪怪的要求啦,全是负值的时候最大值是0,然后再输出整个序列的开头值和结尾值。(我这里写的比较乱了,本来是想直接在读入的时候就处理完了,不存到数组里,但最后考虑到这个要求的时候发现好像不太对,但已经不想改了QAQ)
代码
#include<iostream>
using namespace std;
int main() {
int n;
cin >> n;
int current = -1;//记录当前子序列的和
int current_max = -1;//记录最大子序列的和
int start_max = -1;//记录最大子序列开头值
int end_max = -1;//记录最大子序列结尾值
int flag = 0;//记录是否有写入过current_max,其实就是记录是否有非负值
int start = 0;//记录当前子序列的开头值
int end = 0;//记录当前子序列的结尾值
int first = 0;//记录整个序列的开头值
int last = 0;//记录整个序列的结尾值
int t;
for (int i = 0; i < n; ++i) {
cin >> t;
if (i == 0) {//整个序列开头值
first = t;
}
else if (i == n - 1) {//整个序列结尾值
last = t;
}
if (current < 0) {//如果之前的子序列和小于0,就重新开始子序列
start = t;
end = t;
current = 0;//同时当前和置为0
}
current += t;//加上新的一个值
end = t;//记录当前子序列的结尾值
if (current > current_max) {//记录最大子序列的和、开头、结尾
flag = 1;//flag置1,表示有非负的值存在(因为一开始的current_max是-1,为什么不设成0呢,因为如果有一个0输入,那么就不会记录最大子序列了,会被认为全是负数)
current_max = current;
start_max = start;
end_max = end;
}
}
if (flag==0) {//全负数时
current_max = 0;
start_max = first;
end_max = last;
}
cout << current_max << " " << start_max << " " << end_max << endl;
return 0;
}
}