题目描述
给出一个长度为 n 的序列 a,选出其中连续且非空的一段使得这段和最大。
输入格式
第一行是一个整数,表示序列的长度 n。
第二行有 n 个整数,第 i 个整数表示序列的第 i 个数字 ai。
输出格式
输出一行一个整数表示答案。
输入输出样例
输入:
7
2 -4 3 -1 2 -4 3输出:
4
一、首先找规律
以上面的样例为例
1.首先输入“7”就不多说了
2.随后具题意我们需要找到一段数字(例如:2 -4 3)中间不能有断连,所以我们需要找出一段中数字的和最大的一段(不止一段,最大的是唯一的)。
3.其中我们可以发现
举例:
2+(-4)=-2
-2>-4(成立,然后标记,与标记过的比大小,取最大的)
但当-4+3的时候却等于-1(与标记过的比大小,取最大的)
众所周知-1小于3,所以直接舍去这一段(从2开始的)
综上所述我们在从3开始算段
3+(-1)=2
2>-1(成立,然后标记,与标记过的比大小,取最大的)
2+2=4
4>2(成立,然后标记,与标记过的比大小,取最大的)
4+(-4)=0
0>-4(成立,然后标记,与标记过的比大小,取最大的)
0+3=3
3>0(成立,然后标记,与标记过的比大小,取最大的)
这条思路完全符合规律
“所以,上代码”
#include <iostream>//头文件
using namespace std;
int n, a[200020], b[200020], i, ans = -2000000;
int main()
{
cin >> n;
for (i = 1; i <= n; i++)//因为有n个数所以循环n遍
{
cin >> a[i];//输入
if (i == 1)//在第一遍是需要记录,第二遍开始相加比较
{
b[i] = a[i];//用b[i]存储目前相加起来的数
}
else
{
b[i] = max(a[i], b[i - 1] + a[i]);//筛选相加并比较
}
ans = max(ans, b[i]);//筛选总和
}
cout << ans;//输出
system("pause");//我编译器需要
return 0;
}
看完这,其实大家可以发现这个代码不需要数组,所以:
#include <iostream>
using namespace std;
int n, a, b, i, ans = -2000000;
int main()
{
cin >> n;
for (i = 1; i <= n; i++)
{
cin >> a;
if (i == 1)
{
b = a;
}
else
{
b = max(a, b + a);
}
ans = max(ans, b);
}
cout << ans;
system("pause");
return 0;
}//不过多讲解了