其他分享
首页 > 其他分享> > [2018.12.9]BZOJ1010 [HNOI2008]玩具装箱toy

[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