4.18模拟赛seq

DP,计算从左往右的最大值和从右往左的最大值

枚举断点,算出两段的最大值

#include<bits/stdc++.h>
#define int long long
#define N 100010
using namespace std;
namespace program{
	int n,a[N],ansl[N],ansr[N],l[N],r[N],ans=-20021109;
	inline void work(){
		scanf("%lld",&n);
		for(int i=1;i<=n;i++)
			scanf("%lld",&a[i]);
		memset(ansl,-20021109,sizeof ansl);
		memset(ansr,-20021109,sizeof ansr);
		for(int i=1;i<=n;i++)
			l[i]=max((int)0,l[i-1])+a[i],ansl[i]=max(ansl[i-1],l[i]);
		//ansl[i]表示1到第i个数的最大子段和 
		for(int i=n;i>=1;i--)
			r[i]=max(r[i+1],(int)0)+a[i],ansr[i]=max(ansr[i-1],r[i]);
		//ansr[i]表示第n到第i个数的最大子段和
		for(int i=2;i<n;i++)//枚举断点 
			ans=max(ans,ansl[i-1]+ansr[i]);//题目很奇怪 如 -1 1 -1 可以取 一段 1 和一段 -1 ;而不用中间隔一个 
		printf("%lld\n",ans);
	}
}
signed main(){
	freopen("seq.in","r",stdin);
	freopen("seq.out","w",stdout);
	program::work();
	return 0;
}

阅读更多
换一批

没有更多推荐了,返回首页