bzoj1010: [HNOI2008]玩具装箱toy
题目
斜率优化dp
原方程
f[i]=min{f[j]+(i−j−1−L+sum[i]−sum[j])2}
f
[
i
]
=
m
i
n
{
f
[
j
]
+
(
i
−
j
−
1
−
L
+
s
u
m
[
i
]
−
s
u
m
[
j
]
)
2
}
<script type="math/tex" id="MathJax-Element-122">f[i]=min{\lbrace f[j]+(i-j-1-L+sum[i]-sum[j])^2\rbrace}</script>
斜率优化后
i+1+L+sum[i]>=f[j]+(j+sum[j])2−f[k]−(k+sum[k])22(j+sum[j]−k−sum[k])
i
+
1
+
L
+
s
u
m
[
i
]
>=
f
[
j
]
+
(
j
+
s
u
m
[
j
]
)
2
−
f
[
k
]
−
(
k
+
s
u
m
[
k
]
)
2
2
(
j
+
s
u
m
[
j
]
−
k
−
s
u
m
[
k
]
)
<script type="math/tex" id="MathJax-Element-123">i+1+L+sum[i]>=\frac{f[j]+(j+sum[j])^2-f[k]-(k+sum[k])^2}{2(j+sum[j]-k-sum[k])}</script>
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=50002;
int n,i,h,t;
ll sum[N],q[N],f[N],L;
ll sqr(ll x){return x*x;}
#define get(i,j) f[j]+sqr(sum[i]-sum[j]+i-j-1-L)
#define up(i,j) (f[i]+sqr(i+sum[i])-f[j]-sqr(j+sum[j]))
#define down(i,j) (i+sum[i]-j-sum[j])*2
inline char gc(){
static char buf[100000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++;
}
#define gc getchar
inline int read(){
int x=0,fl=1;char ch=gc();
for (;ch<48||ch>57;ch=gc())if(ch=='-')fl=-1;
for (;48<=ch&&ch<=57;ch=gc())x=(x<<3)+(x<<1)+(ch^48);
return x*fl;
}
int main(){
n=read();L=read();
for (i=1;i<=n;i++) sum[i]=read(),sum[i]+=sum[i-1];
t=1;
for (i=1;i<=n;i++){
while (h+1<t && up(q[h+1],q[h])<=down(q[h+1],q[h])*(i-1-L+sum[i])) h++;
f[i]=get(i,q[h]);
while (h+1<t && up(i,q[t-1])*down(q[t-1],q[t-2])<=up(q[t-1],q[t-2])*down(i,q[t-1])) t--;
q[t++]=i;
}
printf("%lld",f[n]);
}
浙公网安备 33010602011771号