题目描述
给出一个长度为 nn 的序列 aa,选出其中连续且非空的一段使得这段和最大。
输入格式
第一行是一个整数,表示序列的长度 nn。
第二行有 nn 个整数,第 ii 个整数表示序列的第 ii 个数字 a_iai。
输出格式
输出一行一个整数表示答案。
输入输出样例
输入
7 2 -4 3 -1 2 -4 3
输出
4
思路:求取最大子段和,一开始想到用暴力破解法,分别以每个数组元素作为子段的初始,求取子段中的最大值,想法简单粗暴,对于较小的测试样例适用,但对于较大的测试样例很容易超时。
#include <iostream>
using namespace std;
int main(void)
{
int n;
cin >> n;
int* a = new int[n];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
int sum = 0;
int i,flag = 0;
for (i = 0; i < n; i++) {
if (a[i] != 0) {
flag = 1;
break;
}
}
int min = a[0], max = a[0];
if (flag == 0) {
for (int j = 1; j < n; j++) {
if (a[j] < min) {
min = a[j];
}
cout << a[j];
}
}
else {
for (int j = 0; j < n; j++) {
sum = 0;
for (int k = j; k < n; k++) {
sum = sum + a[k];
if (sum > max) {
max = sum;
}
}
}
cout << max;
}
delete[]a;
return 0;
}
分析该题,将第一个元素作为有序数列,如若某一元素加上前一个元素的值大于原先的值,则将该元素加上上一个元素的值作为该有序数列的值,如果加上前一个元素的值后变小,则将该元素的值直接作为有序数列的值,最后的结果是判断该有序数列的最大值。
AC参考代码:
#include <iostream>
#include <cmath>
using namespace std;
int max(int m, int n) { //定义max函数,返回两个数中较大的数
if (m > n) {
return m;
}
else {
return n;
}
}
int main(void)
{
int n;
cin >> n;
int* a = new int[n]; //动态创建数组存储输入的数据
int* b = new int[n];
for (int i = 0; i < n; i++) {
cin >> a[i];
}
b[0] = a[0];
int mx = a[0]; //
for (int i = 1; i < n; i++) {
b[i] = max(a[i], a[i] + b[i - 1]);
mx = max(mx, b[i]);
}
cout << mx;
}