题解:dp
#include<stdio.h>
#include<algorithm>
using namespace std;
#define se 0x3f3f3f3f
int n;
int f[100005];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
f[i]=max(f[i-1]+x,x);
}
int ans=-se;
for(int i=1;i<=n;i++)
{
ans=max(ans,f[i]);
}
printf("%d",ans);
}
我的方法:
求前缀和,对于每个点找到左面(包括这点)最小的和右面(包括这点)最大的,做差。注意:如果差为零,则选择的长度为0,不符合题意。
#include<stdio.h>
#include<algorithm>
using namespace std;
typedef long long ll;
#define inf 100005
#define se 0x3f3f3f3f
ll n;
ll a[inf];
ll sum[inf];
ll ans=-se;
ll minn[inf],maxn[inf];
int main()
{
scanf("%lld",&n);
for(ll i=1;i<=n;i++)
{
scanf("%lld",&a[i]);
ans=max(ans,a[i]);
sum[i]=sum[i-1]+a[i];
ans=max(ans,sum[i]);
}
minn[1]=sum[1];
for(ll i=2;i<=n;i++)
{
if(sum[i]<minn[i-1])
{
minn[i]=sum[i];
}else
{
minn[i]=minn[i-1];
}
}
maxn[n]=sum[n];
for(ll i=n-1;i>=1;i--)
{
if(sum[i]>maxn[i+1])
{
maxn[i]=sum[i];
}else
{
maxn[i]=maxn[i+1];
}
}
for(ll i=1;i<=n;i++)
{
if(minn[i]==maxn[i])continue;
ans=max(ans,maxn[i]-minn[i]);
}
printf("%lld",ans);
}