P1115 最大子段和

题目描述

       给出一个长度为n的序列a,选出其中连续且非空的一段使得这段和最大

输入格式

       第一行是一个整数,表示序列的长度n。

       第二行有n个整数,第i个整数表示序列的第i个数字a_i。

输出格式

       输出一行一个整数表示答案。

输入输出样例

输入 #1

7
2 -4 3 -1 2 -4 3

输出 #1

4

说明/提示

样例 #1 解释

选取[3,5]子段{3,−1,2},其和为4。

数据规模与约定
  • 对于40%的数据,保证1≤n≤2×10^3。
  • 对于100%的数据,保证1≤n≤2×10^5,-10^4≤a_i≤10^4。

分析:

       这道题最好用动态规划,用一个数组dp[i]存储当前的最大子段和,也就是当n=i时的最大子段和,接下来我们要找出状态转移方程。

       而状态转移方程是什么呢?我们可以想一想,当a[i]为负数,如果n=i-1时的最大子段和比这个负数a[i]还小,那n=i时的最大子段和就是a[i]。当a[i]为正数,如果n=i-1时的最大子段和为负数的时候,加上了a[i]并不比a[i]本身大。所以状态转移方程也就是dp[i]=max(dp[i]-1+a[i],a[i])。但因为有时候dp[n]也不是最优答案,于是要用一个变量保存dp数组中的最大值,其他的输入输出我就不说了,下面展示代码。

代码

#include<bits/stdc++.h>
using namespace std;
int n,a[200005],dp[200005]; 
int main(){
	cin>>n;
	for(int i = 1;i<=n;i++) cin>>a[i];
	dp[1] = a[1];//因为题目说非空,所以开始要给dp[1]赋值
	int mx = -214748364;//保存dp数组中的最大值
	for(int i = 2;i<=n;i++)
    {
		dp[i] = max(dp[i-1] + a[i],a[i]);//dp方程式
		mx = max(dp[i],mx);//找最优答案
	}
	cout<<mx;
	return 0;
}

总结:

       题目中有许多坑:1.子段要连续。2.子段要非空。3.序列有负数。但只要考虑完所有情况,找到状态转移方程就好了。

---------------------------------------------------------------------------------------------------------------------------------

点赞+关注,刷题不迷路!!!!!!!!!!!!!!!!!!
---------------------------------------------------------------------------------------------------------------------------------

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值