zoukankan      html  css  js  c++  java
  • [HNOI2008]玩具装箱

    link

    试题分析

    设$dp[i]$表示为去选择第$i$个位最后一个的总价值。复杂度:$O(n^2)$

    将$s[i]=sum_{i=1}^i {c[i]}$,然后$a_i=s_i+i,b_i=s_i+i+1+L$,所以$dp[i]=min{dp[j]+(a[i]-b[j])^2}$

    得:$f[j]+b[j]^2=2 imes a[i] imes b[j]+f[i]-a[i]^2$

    发现$f[j]+b[j]^2$设为$Y$,$2 imes a[i]$为斜率,$b[j]$设为$X$,我们发现要求截距最短,即为下凸壳。然后就可以斜率优化了

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<climits>
    #define int long long
    using namespace std;
    inline int read(){
        int f=1,ans=0;char c=getchar();
        while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
        while(c>='0'&&c<='9'){ans=ans*10+c-'0';c=getchar();}
        return f*ans;
    }
    const int N=50001;
    int Y[N],X[N];
    int f[N],s[N],n,L,a[N],b[N],l,r,que[N];
    signed main(){ 
        memset(f,127/3,sizeof(f));
        n=read(),L=read();
        for(int i=1;i<=n;i++) s[i]=s[i-1]+read();
        for(int i=0;i<=n;i++) a[i]=s[i]+i,b[i]=s[i]+i+1+L;
        l=1,r=1,que[1]=0,f[0]=0;Y[0]=f[0]+b[0]*b[0],X[0]=b[0]; 
        for(int i=1;i<=n;i++){
            while(l<r&&Y[que[l+1]]-Y[que[l]]<=2*a[i]*(X[que[l+1]]-X[que[l]]))  l++;
            f[i]=f[que[l]]+(a[i]-b[que[l]])*(a[i]-b[que[l]]);
            X[i]=b[i],Y[i]=f[i]+b[i]*b[i];
            while(l<r&&(Y[que[r]]-Y[que[r-1]])*(X[i]-X[que[r]])>=(X[que[r]]-X[que[r-1]])*(Y[i]-Y[que[r]])) r--;
            que[++r]=i;
        }cout<<f[n];
    }
    View Code
  • 相关阅读:
    [bzoj1251]序列终结者
    Codeforces #Round 406(Div.2)
    [3.23校内训练赛]
    [APIO2009]
    [APIO2016]
    [bzoj1901]动态区间k大
    [9018/1904]火星商店
    [bzoj3673/3674可持久化并查集加强版]
    [bzoj1297][SCOI2009]迷路
    [bzoj1218][HNOI2003]激光炸弹
  • 原文地址:https://www.cnblogs.com/si-rui-yang/p/10109050.html
Copyright © 2011-2022 走看看