题目描述
英文
中文大意
给定 K 个整数序列,获取它的最大子序列之和
在一行内首先输出最大子序列之和,并输出子序列的头和尾
如果最大子序列不是唯一,输出最小的 i、j
的组合
如果全部 K 个整数 都是负数——你应该输出最大值为 0 i、j
为第一个和最后一个的索引
样例
思路分析
看子序列问题,首先想到滑动窗口,但是好像行不通
暴力法不考虑
思考动态规划
设定一个临时值temp
来存储目前的子序列和
设定一个标志变量flag
来判断,如果所有的seq中的数都是负数,则输出特情
code
#include <iostream>
using namespace std;
int main() {
// seq长度
int n;
cin >> n;
bool flag = true;
// 此处sum定义为 -1 是处理最大值为0的特殊情况
int temp = 0, sum = -1, left = 0, right = n - 1, tempIndex = 0, seq[n];
for (int i = 0;i < n;i++) {
cin >> seq[i];
// 特情排查
if (seq[i] >= 0) flag = false;
temp += seq[i];
// 小于0的子序列可以排除掉 移动left
if (temp < 0) {
// 移动左索引 i 更新temp的值
temp = 0;
tempIndex = i + 1;
} else if (temp > sum) {
// 更新最大值 和 索引
sum = temp;
left = tempIndex;
right = i;
}
}
if (flag) cout << 0 << " " << seq[0] << " " << seq[n-1];
else cout << sum << " " << seq[left] << " " << seq[right];
// if (flag) sum = 0;
// cout << sum << " " << seq[left] << " " << seq[right];
return 0;
}
需要注意的判定点
// 因为是整数 所以 sum 是负数里最小的 如果设为 0 在最大值为 0 时会出问题
int sum = -1;
bool flag = true;
// 如果 非负 则设置flag为false
// 网上看到大佬们可以不设置flag 不过个人感觉这样可读性会好一点
if (seq[i] >= 0) flag = false;