怎么办,阳历没过!

最大子段和

题目描述

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

输入格式

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

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

输出格式

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

样例 #1

样例输入 #1

7
2 -4 3 -1 2 -4 3

样例输出 #1

4

提示

样例 1 解释

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

数据规模与约定

  • 对于 40\% 的数据,保证 $n \leq 2 \times 10^3$。
  • 对于 100\% 的数据,保证 $1 \leq n \leq 2 \times 10^5$,$-10^4 \leq a_i \leq 10^4$。

这是我的代码

#include <iostream>
#include <limits.h>
#include <cmath>

using std::cin;
using std::cout;

int a[200010];
int n;

int max(int x,int y)
{
	using std::max;
	return max(x,y);
}

int find_max_crossing(int l,int r,int mid)
{
	
	int left_sum=INT_MIN , right_sum=INT_MIN;
	
	int tmp_sum=0;
	for (int i=mid;i>=l;i--)
	{
		tmp_sum+=a[i];
		if (tmp_sum>left_sum)
			left_sum=tmp_sum;
	}
	
	tmp_sum=0;
	for (int i=mid;i<=r;i++)
	{
		tmp_sum+=a[i];
		if (tmp_sum>right_sum)
		{
			right_sum=tmp_sum;
		}
	}
	
	return (left_sum+right_sum);
}

int find_max(int l,int r)
{
	if (l==r)
	{
		return a[l];
	}
	
	else 
	{
		int mid=(l+r)/2;
		
		int a=find_max(l,mid);
		int b=find_max(mid+1,r);
		int c=find_max_crossing(l,r,mid);
		
		return max(a,max(b,c));
	}
}

int main()
{
	cin>>n;
	for (int i=1;i<=n;i++)
	{
		cin>>a[i];
	}
	
	cout<<find_max(1,n);
	return 0;
}

// output : 6
3 个赞

样例 1 解释

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

数据规模与约定

  • 对于 40% 的数据,保证 n≤2×10^3。
  • 对于 100% 的数据,保证 1≤n≤2×10^5,−10^4≤ai​≤10^4。
4 个赞

有用给个解决方案
蟹蟹

4 个赞

行, 找到错误了,在find_max_crossing函数中第二个循环条件里,i应该从mid+1开始

2 个赞