目录:
题目:
分析:
超级水的贪心,直接
过。
但小编就是想学下分治,所以介绍下分治的做法,顺便
一下。
我们将整个数列最左设为
,最右设为
,中间位置设为
。
然后我们就可以发现,最大值的位置一定在三个地方:
1.从
一直加到
——
2.从
一直加到
(包含
)
3.从
(包含
)一直加到
第2、3点我们可以通过递归实现,所以整套题目的时间复杂度是:
代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#define LL long long
using namespace std;
const int fu=-99999999;
inline LL read() {
LL d=0,f=1;char s=getchar();
while(s<'0'||s>'9'){if(s=='-')f=-1;s=getchar();}
while(s>='0'&&s<='9'){d=d*10+s-'0';s=getchar();}
return d*f;
}
int max(int x,int y)
{
return x>y? x:y;
}
int x[200001];
int n=read();
int rec(int l,int r)
{
if(l==r) return x[l];
int mid=(l+r)>>1;
int sum=0,ml=fu,mr=fu;
for(int i=mid;i>=l;i--)
{
sum+=x[i];
ml=max(ml,sum);
}
sum=0;
for(int i=mid+1;i<=r;i++)
{
sum+=x[i];
mr=max(mr,sum);
}
return max(max(rec(l,mid),rec(mid+1,r)),mr+ml);
}
int main()
{
for(int i=1;i<=n;i++) x[i]=read();
printf("%d",rec(1,n));
return 0;
}