1. 程式人生 > >特別行動隊-斜率優化

特別行動隊-斜率優化

我們 blank 展開 pre 一個 get 常數 max problem

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],也是可以的,大家可以自己試試。

特別行動隊-斜率優化