简单的最大子序列问题,刘汝佳的书里有分治的解法,我用的吴大大讲的线性遍历的方法。
maxx[j]=s[j]+max{0,maxx[j-1]},就这样先遍历一遍,求出以各个车站为终点的路线的最大值,再遍历一次找打符合题意的最大值即可ac。
这种题还可以衍生出两段循环最大子段和问题。
#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAX 20100
using namespace std;
int ss[MAX],maxx[MAX],start[MAX];
int main()
{
int t,i,j,p,s,front,rear,sum;
scanf("%d",&t);
for(i=1;i<=t;i++)
{
sum=0,rear=front=0;
scanf("%d",&s);
for(j=0;j<s-1;j++)
scanf("%d",&ss[j]);
maxx[0]=ss[0],start[0]=1;//二号stop
for(p=1;p<s-1;p++)
{
if(maxx[p-1]>=0)
{
maxx[p]=maxx[p-1]+ss[p];
start[p]=start[p-1];
}
else
{
maxx[p]=ss[p];
start[p]=p+1;
}
}
for(j=s-2;j>=0;j--)
{
if(maxx[j]>sum)
{
sum=maxx[j];
front=start[j];
rear=j+2;
}
else if(maxx[j]==sum)
{
if(j+2-start[j]>rear-front)
{
sum=maxx[j];
front=start[j];
rear=j+2;
}
else if(j+2-start[j]==rear-front&&start[j]<front)
{
sum=maxx[j];
front=start[j];
rear=j+2;
}
}
}
if(sum<=0)
printf("Route %d has no nice parts\n",i);
else
printf("The nicest part of route %d is between stops %d and %d\n",i,front,rear);
}
return 0;
}