题面
题目描述
给出一个长度为 n n n 的序列 a a a,选出其中连续且非空的一段使得这段和最大。
输入格式
第一行是一个整数,表示序列的长度
n
n
n。
第二行有
n
n
n 个整数,第
i
i
i 个整数表示序列的第
i
i
i 个数字
a
i
a_i
ai。
输出格式
输出一行一个整数表示答案。
样例
输入
7
2 -4 3 -1 2 -4 3
输出
4
样例解释
选取 [ 3 , 5 ] [3, 5] [3,5] 子段 { 3 , − 1 , 2 } \{3, -1, 2\} {3,−1,2},其和为 4 4 4。
数据规模
对于
40
%
40\%
40% 的数据,保证
n
≤
2
×
1
0
3
n \leq 2 \times 10^3
n≤2×103。
对于
100
%
100\%
100% 的数据,保证
1
≤
n
≤
2
×
1
0
5
1 \leq n \leq 2 \times 10^5
1≤n≤2×105 ,
−
1
0
4
≤
a
i
≤
1
0
4
-10^4 \leq a_i \leq 10^4
−104≤ai≤104。
解析
FLYing名言:如果一道题可以模拟,又像贪心,那么它一定是动态规划
用
f
i
f_i
fi表示第
i
i
i个数字前的最大值
易得:
{
f
i
=
f
i
−
1
(
f
i
≤
f
i
−
1
)
f
i
=
n
u
m
i
(
f
i
>
f
i
−
1
)
\left\{ \begin{aligned} f_i&=f_{i-1} &(f_i\le f_{i-1})\\ f_i&=num_i &(f_i>f_{i-1})\\ \end{aligned} \right.
{fifi=fi−1=numi(fi≤fi−1)(fi>fi−1)
因为
f
i
f_i
fi的计算中只会用到
f
i
−
1
f_{i-1}
fi−1和
n
u
m
i
num_i
numi,所以可以压缩:
a
n
s
=
max
i
=
1
N
{
max
(
f
,
n
u
m
)
}
ans=\max_{i=1}^{N}\left\{\max\left(f,num\right)\right\}
ans=i=1maxN{max(f,num)}
f
=
max
(
f
,
n
u
m
)
f=\max\left(f,num\right)
f=max(f,num)
代码
#include<bits/stdc++.h>
using namespace std;
int N,ans=-10000000;
int num,f;
int max(int a,int b){return a>b?a:b;}
int main(){
scanf("%d",&N);
for(int i=1;i<=N;i++){
scanf("%d",&num);
f=max(f+num,num);
ans=max(ans,f);
}
printf("%d",ans);
}