After you've done this, you're really understanding the slope optimization DP
According to the state transfer equation F[i]=max (f[j]+ax^2+bx+c), X=sum[i]-sum[j]
can be deformed to F[i]=max ((A*sum[j]^2-b*sum[j])-(2a*sum[j]*sum[i]) + (A*SUM[I]^2+B*SUM[I]+C)
We can map each decision to a point on the plane
where x coordinates (A*SUM[J]^2-B*SUM[J]) represent the fixed value of this decision (unrelated to where it was transferred)
the y-coordinate is -(2a*sum[j]) represents the potential value of this decision (in relation to where it was transferred)
So that we can begin to maintain a convex hull with an x increment y decreasing in a monotone queue.
------------------------------------------------------------------------
For each new element that joins in
Let's first judge the first two decisions of the team if the existing value of a decision is inferior to the decision then delete it.
(because the underlying value of the decision in the maintained monotone queue is incremented)
Then update the maximum value of the newly added element
And then judge the two decisions between the new plus element and the end of the team.
If the first decision at the end of the team is within the convex hull of the new plus decision and all the preceding decisions
then this decision can never be better than the previous decision and the new plus decision so just erase it.
Finally add the new decision to the monotone queue
#include <cstdio>#include<cstring>#include<cmath>#include<algorithm>#defineRep (i,n) for (int i=1;i<=n;++i)#defineIMAX (x, y) (x>y?x:y)#defineImin (x, y) (x<y?x:y)using namespacestd;Const intn=1000010;intSum[n],q[n];Long LongF[n];intN;Long Longa,b,c;Long LongSolveintXinty) { returnf[x]+a* (Sum[y]-sum[x]) * (Sum[y]-sum[x]) +b* (sum[y]-sum[x]) +C;}Long LongSolvex (intx) { returnf[x]+a*sum[x]*sum[x]-b*sum[x];}BOOLJudgeintXintYintz) { Long LongTx=solvex (x), Ty=solvex (y), tz=Solvex (z); return(TY-TX) * (Sum[z]-sum[x]) <= (TZ-TX) * (Sum[y]-sum[x]);//about to drop -2a.}intMain () {scanf ("%d",&N); scanf ("%lld%lld%lld",&a,&b,&c); Rep (i,n) {scanf ("%d",&Sum[i]); Sum[i]+=sum[i-1]; } intIfront=1, itail=1; q[1]=0; Rep (i,n) { while(Ifront<itail&&solve (Q[ifront],i) <=solve (q[ifront+1],i))++Ifront; F[i]=solve (q[ifront],i); while(Ifront<itail&&judge (q[itail-1],q[itail],i))--Itail; q[++itail]=i; } printf ("%lld", F[n]); return 0;}
APIO2010 Special Ops Team & Slope optimization DP Introductory explanation