最大连续子序列和

引言

这道题在很多的笔试面试和研究生机试中都出现过很多次,并且这道题不是很难想出来,所以还是非常的重要的,话不多说,直接开讲。


一、题目描述

给定一个包含 K 个整数的序列 N 1 , N 2 , … , N K 。 给定一个包含 K 个整数的序列 {N1,N2,…,NK}。 给定一个包含K个整数的序列N1,N2,,NK

连续子序列定义为 N i , N i + 1 , … , N j ,其中 1 ≤ i ≤ j ≤ K 。 连续子序列定义为 {Ni,Ni+1,…,Nj},其中 1≤i≤j≤K。 连续子序列定义为Ni,Ni+1,,Nj,其中1ijK

最大子序列是指序列内各元素之和最大的连续子序列。 最大子序列是指序列内各元素之和最大的连续子序列。 最大子序列是指序列内各元素之和最大的连续子序列。

例如,给定序列 − 2 , 11 , − 4 , 13 , − 5 , − 2 ,它的最大子序列为 11 , − 4 , 13 ,其各元素之和为 20 。 例如,给定序列 {−2,11,−4,13,−5,−2},它的最大子序列为 {11,−4,13},其各元素之和为 20。 例如,给定序列2,11,4,13,5,2,它的最大子序列为11,4,13,其各元素之和为20

现在你需要求出最大子序列的各元素之和。 现在你需要求出最大子序列的各元素之和。 现在你需要求出最大子序列的各元素之和。

输入格式 输入格式 输入格式
第一行包含一个整数 K 。第二行包含 K 个整数。 第一行包含一个整数 K。第二行包含 K 个整数。 第一行包含一个整数K。第二行包含K个整数。

输出格式 输出格式 输出格式
输出一个整数,表示最大子序列的各元素之和。 输出一个整数,表示最大子序列的各元素之和。 输出一个整数,表示最大子序列的各元素之和。

设最大子序列为 N i , N i + 1 , … , N j ,如果答案不唯一,则选择 i 更小的解,如果仍不唯一,则选择 j 更小的解。 设最大子序列为 {Ni,Ni+1,…,Nj},如果答案不唯一,则选择 i 更小的解,如果仍不唯一,则选择 j 更小的解。 设最大子序列为Ni,Ni+1,,Nj,如果答案不唯一,则选择i更小的解,如果仍不唯一,则选择j更小的解。

注意,我们规定,如果所有 K 个数字均为负数,则其最大和定义为 0 ,并且应该输出整个序列的第一个数字 注意,我们规定,如果所有 K 个数字均为负数,则其最大和定义为 0,并且应该输出整个序列的第一个数字 注意,我们规定,如果所有K个数字均为负数,则其最大和定义为0,并且应该输出整个序列的第一个数字
和最后一个数字。 和最后一个数字。 和最后一个数字。

数据范围 数据范围 数据范围
1 ≤ K ≤ 10000 , 序列内元素的绝对值不超过 1 0 5 。 1≤K≤10000,序列内元素的绝对值不超过 10^5。 1K10000,序列内元素的绝对值不超过105


二、思路1:DP

思路: 这道题可以拿 D P DP DP 来做, f [ i ] f[i] f[i] 代表以 i i i 为结尾的最大子序列和,就只有两种情况跟上一个数合并,要么自己另成一个新的开始,然后在这两种选择中选最大,最后再求最大值即可。

示例代码:

#include <iostream>

using namespace std;

const int N = 1e4+10;

int n;
int a[N], f[N];

int main()
{
	cin >> n;
	for(int i = 1; i <= n; ++i) cin >> a[i];
	
	int res = 0;
	for(int i = 1; i <= n; ++i)
	{
		f[i] = max(f[i-1] + a[i], a[i]);
		if(f[i] > res) res = f[i];
	}

	cout << res << endl;
	
	return 0;
}

三、思路2:贪心

思路:贪心其实就是如果连续区间的和为非负,那么就一直加下去,否则就从当前重新开始。

示例代码:

#include <iostream>

using namespace std;

const int N = 1e4+10;

int n;
int a[N];

int main()
{
    cin >> n;
    for(int i = 1; i <= n; ++i) cin >> a[i];
    
    int sum = 0, res = -2e9;
    for(int i = 1; i <= n; ++i)
    {
        sum += a[i];
        res = max(res, sum);
        if(sum < 0) sum = 0;
    }
    
    cout << res << endl;
    
    return 0;
}
  • 7
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lijiachang030718

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值