用三个断点将整个序列分成四个子序列,使得其计算和最大,输出三个断点的位子。
思路:
设定D【i】【j】表示以i作为起点,以j作为一个断点,将区间【i,n】分成两部分的计算和。
那么我们通过上述预处理,可以得到best【i】,D【i】【j】的最大值,同时维护一个数组pos【i】,表示best【i】条件下的最优解的j的位子。
那么我们可以O(n^2)去枚举前两个断点 ,然后通过得到pos【i】数组来得到第三个位子,整体维护一个最大值取最优即可。
Ac代码:
#include<stdio.h>
#include<string.h>
using namespace std;
#define ll __int64
ll d[5005][5005];
ll best[5005];
ll pos[5005];
ll a[5005];
ll sum[5005];
int main()
{
ll n;
while(~scanf("%I64d",&n))
{
memset(sum,0,sizeof(sum));
for(ll i=1;i<=n;i++)scanf("%I64d",&a[i]);
for(ll i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
for(ll i=1;i<=n+1;i++)
{
best[i]=-1000000000000000000;
for(ll j=i;j<=n+1;j++)
{
d[i][j]=(sum[j-1]-sum[i-1])-(sum[n]-sum[j-1]);
if(d[i][j]>best[i])
{
best[i]=d[i][j];
pos[i]=j;
}
}
}
ll maxn=-1000000000000000000;
ll ans1,ans2,ans3;
for(ll i=1;i<=n+1;i++)
{
for(ll j=i;j<=n+1;j++)
{
if(sum[i-1]-(sum[j-1]-sum[i-1])+best[j]>maxn)
{
maxn=sum[i-1]-(sum[j-1]-sum[i-1])+best[j];
ans1=i-1,ans2=j-1,ans3=pos[j]-1;
}
}
}
printf("%I64d %I64d %I64d\n",ans1,ans2,ans3);
}
}

本文介绍了一种算法,用于解决将整数序列通过三个断点分为四个子序列的问题,目标是找到一种划分方式使计算得出的总和最大。文章详细阐述了如何使用预处理方法确定最佳断点位置,并通过双重循环实现高效求解。
299

被折叠的 条评论
为什么被折叠?



