BZOJ 1010: [HNOI2008]玩具装箱toy | 单调队列优化DP
原题:
http://www.lydsy.com/JudgeOnline/problem.php?id=1010
题解:
#include<cstdio> #include<algorithm> #include<cstring> #define N 50005 typedef long long ll; using namespace std; ll n,c[N],a[N],b[N],sum[N],f[N],L,q[N],l,r; ll sq(ll x){return x*x;} double getD(ll j,ll k) { return 1.0*(f[j]+sq(b[j])-f[k]-sq(b[k]))/(2*(b[j]-b[k])); } int main() { scanf("%lld%lld",&n,&L); for (ll i=1;i<=n;i++) { scanf("%lld",&c[i]); sum[i]=sum[i-1]+c[i]; a[i]=sum[i]+i-1-L; b[i]=sum[i]+i; } for (ll i=1;i<=n;i++) { while (l<r && getD(q[l],q[l+1])<(double)a[i]) l++; ll t=q[l]; f[i]=f[t]+sq(b[t])-2*a[i]*b[t]+sq(a[i]); while (l<r && getD(q[r],i)<getD(q[r-1],q[r])) r--; q[++r]=i; } printf("%lld\n",f[n]); return 0; }