[DP]最大子段和

题面

题目描述

给出一个长度为 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 n2×103
对于 100 % 100\% 100% 的数据,保证 1 ≤ n ≤ 2 × 1 0 5 1 \leq n \leq 2 \times 10^5 1n2×105 − 1 0 4 ≤ a i ≤ 1 0 4 -10^4 \leq a_i \leq 10^4 104ai104

解析

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=fi1=numi(fifi1)(fi>fi1)
因为 f i f_i fi的计算中只会用到 f i − 1 f_{i-1} fi1 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);
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值