[BZOJ1911]特别行动队

来源:互联网 发布:大型企业网络建设论文 编辑:程序博客网 时间:2024/04/28 19:08

题目描述

这里写图片描述

题解

我们可以得到裸的dp:f[i]=f[j]+(sum[i]sum[j])2a+(sum[i]sum[j])b+c
然后展开。
f[i]=f[j]+asum[i]22asum[i]sum[j]+asum[j]2+bsum[i]bsum[j]+c
然后整理,准备斜率优化,最后得到
f[j]+asum[j]2bsum[j]=2asum[i]sum[j]+f[i]asum[i]2bsum[i]c
y=f[j]+asum[j]2bsum[j]
k=2asum[i]
x=sum[j]

然后就可以愉快的斜率优化了。

代码

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<cmath>#include<algorithm>#define F(i,j,n) for(int i=j;i<=n;i++)#define D(i,j,n) for(int i=j;i>=n;i--)typedef long long ll;const int maxn = 100000+10;using namespace std;int n,l,r;ll a,b,c,q[maxn],f[maxn],s[maxn];inline int read(){    int x=0,f=1;char ch=getchar();    while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}    while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}    return x*f;}inline double getk(int x,int y){    return (double)((f[x]+a*s[x]*s[x]-b*s[x])-(f[y]+a*s[y]*s[y]-b*s[y]))/(double)(s[x]-s[y]);}int main(){    n=read();a=read();b=read();c=read();    F(i,1,n) s[i]=s[i-1]+read();    l=r=1;q[1]=0;    F(i,1,n)    {        while (l<r&&getk(q[l],q[l+1])>a*s[i]*2) l++;        f[i]=f[q[l]]+a*s[q[l]]*s[q[l]]-b*s[q[l]]-a*s[i]*s[q[l]]*2+a*s[i]*s[i]+b*s[i]+c;        while (l<r&&getk(q[r-1],q[r])<getk(q[r],i)) r--;        q[++r]=i;    }    printf("%lld\n",f[n]);    return 0;}