特别行动队-斜率优化

APIO2010特别行动队

令S为前缀和,那么n方DP:

f[i]=max{f[i],f[j]+a*(S[i]-S[j])*(S[i]-S[j])+b*(S[i]-S[j])+c};

 展开,移项得到:

f[j]+a*s[j]*s[j]=(2*a*s[i]+b)s[j]+f[i]- a*s[i]*s[i]-b*s[i]-c。

即以f[j]+a*s[j]*s[j]为y,s[j]为x的一次函数,用斜率优化。

因为斜率单调递减,所以维护一个单调递减的上凸壳即可。

 

IL DB Y(int x) {return (DB)f[x]+a*S[x]*S[x];}
IL DB Slope(int x,int y) {return (Y(x)-Y(y))/(DB)(S[x]-S[y]);}
while (L<R&&(DB)2*a*S[i]+b<=Slope(q[L+1],q[L])) ++L;
f[i]=f[q[L]]+a*(S[i]-S[q[L]])*(S[i]-S[q[L]])+b*(S[i]-S[q[L]])+c;
while (L<R&&Slope(i,q[R])>=Slope(q[R],q[R-1])) --R; q[++R]=i;

 

其实我们也可以把常数项b与s[j]的乘积也丢到y那边,斜率就变成了2*a*s[i],也是可以的,大家可以自己试试。

 

转载于:https://www.cnblogs.com/Bhllx/p/10363809.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值