[2018.12.9]BZOJ1010 [HNOI2008]玩具装箱toy
作者:互联网
设\(sum_i\)为\(c_i\)的前缀和。
\(dp_i=min\{dp_j+(i-j-1+sum_i-sum_j-L)^2\}\)
设\(f_i=i+sum_i\),\(t=L+1\)
\(dp_i=min\{dp_j+(f_i-f_j-t)^2\}\)
\(\ \ \ \ \ =min\{dp_j+f_i^2+f_j^2+t^2-2f_if_j-2tf_i+2tf_j\}\)
\(\ \ \ \ \ =min\{dp_j+f_j^2-2f_if_j+2tf_j\}+f_i^2-2tf_i+t^2\)
\(\ \ \ \ \ =-max\{-dp_j-f_j^2+2f_jf_i-2tf_j\}+f_i^2-2tf_i+t^2\)
\(k=2f_j\),\(b=-dp_j-f_j^2-2tf_j\)
\(dp_i=-max\{kf_i+b\}+f_i^2-2tf_i+t^2\)
\(f_x\)单调递增。
套斜率优化即可。
code:
#include<bits/stdc++.h>
using namespace std;
int n,c[50010],line[50010],l,r;
long long t,f[50010],dp[50010],k[50010],b[50010];
long long val(int l1,long long x){
return k[l1]*x+b[l1];
}
bool cov(int l1,int l2,int l3){
return (b[l2]-b[l1])*(k[l1]-k[l3])>=(b[l3]-b[l1])*(k[l1]-k[l2]);
}
int main(){
scanf("%d%lld",&n,&t);
t++;
for(int i=1;i<=n;i++){
scanf("%d",&c[i]);
f[i]=f[i-1]+c[i]+1;
}
l=r=1;
for(int i=1;i<=n;i++){
while(l<r&&val(line[l],f[i])<=val(line[l+1],f[i]))l++;
dp[i]=-val(line[l],f[i])+f[i]*f[i]-2*t*f[i]+t*t;
k[i]=2*f[i];
b[i]=-dp[i]-f[i]*f[i]-2*t*f[i];
while(l<r&&cov(i,line[r-1],line[r]))r--;
line[++r]=i;
}
printf("%lld",dp[n]);
return 0;
}
标签:2tf,2018.12,int,50010,long,toy,l1,HNOI2008,dp 来源: https://www.cnblogs.com/xryjr233/p/BZOJ1010.html