您的位置:首页 > 其它

bzoj1911: [Apio2010]特别行动队

2016-12-01 14:02 281 查看

1911: [Apio2010]特别行动队

Time Limit: 4 Sec  Memory Limit: 64 MB
Submit: 4098  Solved: 1938

[Submit][Status][Discuss]

Description



Input



Output



Sample Input

4

-1 10 -20

2 2 3 4

Sample Output

9

HINT



Source



[Submit][Status][Discuss]
f[i]记录选择i个士兵的最大值

sum[i]=x[1]+x[2]+……x[i-1]+x[i];

f[i]=max(f[j]+a*(sum[i]-sum[j])^2+b*(sum[i]-sum[j])+c)

推斜率方程

j<k<i

         f[j]+a*(sum[i]-sum[j])^2+b*(sum[i]-sum[j])+c <= f[k]+a*(sum[i]-sum[k])^2+b*(sum[i]-sum[k])+c

f[j]+a*(sum[i]-sum[j])^2+b*(sum[i]-sum[j]) <= f[k]+a*(sum[i]-sum[k])^2+b*(sum[i]-sum[k])

f[j]-a*2*sum[i]*sum[j]+a*sum[j]*sum[j]-b*sum[j] <= f[k]-a*2*sum[i]*sum[k]+a*sum[k]*sum[k]-b*sum[k]

f[j]-f[k]+a*sum[j]^2-a*sum[k]^2-b*sum[j]+b*sum[k] <=a*2*sum[i]*sum[j]-a*2*sum[i]*sum[k]

                                                               the same <= sum[i]*2*a*(sum[j]-sum[k])

                           the same / (2*a*(sum[j]-sum[k])) <=sum[i]

  ( f[j]-f[k]+a*sum[j]^2-a*sum[k]^2-b*sum[j]+b*sum[k] )/( 2*a*sum[j]-2*a*sum[k] ) <= sum[i]

SO

slope(j,k)<sum[i]

#include<cstdio>
#include<cstdlib>
#include<cstring>
#define LL long long
const int maxn=1000005;

int n,a,b,c;
LL sum[maxn],f[maxn],q[maxn];

double slope(int j1,int j2)
{
LL x1,x2,y1,y2;
x1=2*a*sum[j1];
x2=2*a*sum[j2];
y1=f[j1]+a*sum[j1]*sum[j1]-b*sum[j1];
y2=f[j2]+a*sum[j2]*sum[j2]-b*sum[j2];
return (y2-y1)/(x2-x1);
}

int main()
{
scanf("%d %d %d %d",&n,&a,&b,&c);
sum[0]=0;
for(int i=1;i<=n;i++)
{
scanf("%lld",&sum[i]);;
sum[i]+=sum[i-1];
}
int l=1,r=1;
q[1]=0;
for(int i=1;i<=n;i++)
{
while(l<r && slope(q[l],q[l+1])<sum[i]) l++;
int j=q[l];
f[i]=f[j]+a*(sum[i]-sum[j])*(sum[i]-sum[j])+b*(sum[i]-sum[j])+c;
while(l<r && slope(q[r-1],q[r])>slope(q[r],i)) r--;
q[++r]=i;
}
printf("%lld",f
);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: