int j2){ return (f[j2]-f[j1]+(s[j2]*s[j2]-s[j1]*s[j1])*a-(s

时间:2021-10-26 06:58:47

【传送门:BZOJ1911】 简要题意:

  有n小我私家,每小我私家都有一个战力值,将这n小我私家分成若干个段(每个段内的人的编号都是持续的),每个段的初始战力值为每个段内的人的战力值的总和

  给出常数a,b,c,,而每个段的真正战力值为ax2+bx+c(x为这个段的初始战力值),求出分成若干个段得到的所有段的最大真正战力值总和

题解:

  DP很容易想到

  设f[i]为将前i小我私家分成若干段的最大真正战力值,s[i]为前i小我私家战力值总和

  可以得到:f[i]=max(f[j]+(s[i]-s[j])*(s[i]-s[j])*a+(s[i]-s[j])*b+c)

  但这道题数据极大

  所以用斜率优化DP

  设j1<j2<i

  f[j2]+(s[i]-s[j2])*(s[i]-s[j2])*a+(s[i]-s[j2])*b+c>f[j1]+(s[i]-s[j1])*(s[i]-s[j1])*a+(s[i]-s[j1])*b+c

  化简得到:(f[j2]-f[j1]+(s[j2]*s[j2]-s[j1]*s[j1])*a-(s[j2]-s[j1])*b)/(s[j2]-s[j1])>2*a*s[i]

  然后做斜率优化就可以了

  注意要加long long

  来自蒟蒻的吐槽:这道题!!我其实应该在n久之前就应该A了,功效在斜率优化的时候把slop(list[head],list[head+1])错手打成了slop(list[head],list[head]+1),痛心疾首

参考代码:

#include<cstdio> #include<cstring> #include<cstdlib> #include<algorithm> #include<cmath> using namespace std; typedef long long LL; LL a,b,c; LL s[1100000]; LL f[1100000]; /* f[i]=max(f[j]+(s[i]-s[j])*(s[i]-s[j])*a+(s[i]-s[j])*b+c) f[i]=max(f[j]+(s[i]-s[j])*(s[i]-s[j])*a+(s[i]-s[j])*b)+c j1<j2<i f[j2]+(s[i]-s[j2])*(s[i]-s[j2])*a+(s[i]-s[j2])*b > f[j1]+(s[i]-s[j1])*(s[i]-s[j1])*a+(s[i]-s[j1])*b f[j2]+s[i]*s[i]*a-2*a*s[i]*s[j2]+s[j2]*s[j2]*a+s[i]*b-s[j2]*b > f[j1]+s[i]*s[i]*a-2*a*s[i]*s[j1]+s[j1]*s[j1]*a+s[i]*b-s[j1]*b f[j2]-2*a*s[i]*s[j2]+s[j2]*s[j2]*a-s[j2]*b > f[j1]-2*a*s[i]*s[j1]+s[j1]*s[j1]*a-s[j1]*b (f[j2]-f[j1]+(s[j2]*s[j2]-s[j1]*s[j1])*a-(s[j2]-s[j1])*b)/(s[j2]-s[j1]) >2*a*s[i] */ LL slop(int j1,int j2) { return (f[j2]-f[j1]+(s[j2]*s[j2]-s[j1]*s[j1])*a-(s[j2]-s[j1])*b)/(s[j2]-s[j1]); } int list[1100000]; int main() { int n; scanf("%d",&n); scanf("%lld%lld%lld",&a,&b,&c); s[0]=0LL; for(int i=1;i<=n;i++) { LL x; scanf("%lld",&x); s[i]=s[i-1]+x; } int head=1,tail=1;list[1]=0; for(int i=1;i<=n;i++) { while(head<tail&&slop(list[head],list[head+1])>2LL*a*s[i]) head++; int j=list[head]; f[i]=f[j]+(s[i]-s[j])*(s[i]-s[j])*a+(s[i]-s[j])*b+c; while(head<tail&&slop(list[tail-1],list[tail])<slop(list[tail],i)) tail--; list[++tail]=i; } printf("%lld\n",f[n]); return 0; }