原题链接
考察:枚举,前缀和
和本题的正解思路有点像的--->Go
题意:
在数组中放三个间断点,使得res最大.
思路:
三个间断点求最值,不能是在前缀区间只取正数,后缀区间只取负数,存在隔了负数出现大正数的情况.
可以枚举中间点mid,求[1,mid]的最大前缀,[mid,n]的最小后缀,两个for循环枚举时间复杂度O(N2)
Code
#include <iostream>
#include <cstring>
using namespace std;
typedef long long LL;
const int N = 5010;
int n;
LL sum[N];
void solve()
{
int pre = 0,mid,ed,sta;
LL res = -1e14;
for(int i=1;i<=n;i++)//枚举中间点,求前缀最大值
{
if(sum[i]>sum[pre]) pre = i;
LL temp = 2*sum[pre]-sum[i];
for(int j=i;j<=n;j++)
{//(0~pre] (pre,i] (i,j] (j,n]
LL t =temp+sum[j]-sum[i]-(sum[n]-sum[j]);
if(t>res)
{
sta = pre;
res = t;
mid = i,ed = j;
}
}
}
printf("%d %d %d\n",sta,mid,ed);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)
{
int x;
scanf("%d",&x);
sum[i]=sum[i-1]+x;
}
solve();
return 0;
}