• BZOJ1010: [HNOI2008]玩具装箱toy


    Time Limit: 1 Sec  Memory Limit: 162 MB

    Description

      P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京。他使用自己的压缩器进行压
    缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中。P教授有编号为1...N的N件玩具,第i件玩具经过
    压缩后变成一维长度为Ci.为了方便整理,P教授要求在一个一维容器中的玩具编号是连续的。同时如果一个一维容
    器中有多个玩具,那么两件玩具之间要加入一个单位长度的填充物,形式地说如果将第i件玩具到第j个玩具放到一
    个容器中,那么容器的长度将为 x=j-i+Sigma(Ck) i<=K<=j 制作容器的费用与容器的长度有关,根据教授研究,
    如果容器长度为x,其制作费用为(X-L)^2.其中L是一个常量。P教授不关心容器的数目,他可以制作出任意长度的容
    器,甚至超过L。但他希望费用最小.

    Input

      第一行输入两个整数N,L.接下来N行输入Ci.1<=N<=50000,1<=L,Ci<=10^7

    Output

      输出最小费用

    Sample Input

    5 4
    3
    4
    2
    1
    4

    Sample Output

    1

    HINT

    Source

    首先O(n^2)的dp方程很容易得到,用f[i]表示前i个玩具装箱所得到的最小花费,sum[i]表示前i个玩具的长度:

    f[i]=min(f[j]+(i-j-1+sum[i]-sum[j]-L)^2)(0<j<i);

    首先进行换元

    设M=L+1,t[i]=sum[i]+i;

    所以即可得到f[i]=min(f[j]+(t[i]-t[j]+m)^2)

    设j<k,j的取值比k更优,则

    f[j]+(t[i]-t[j]-m)^2<f[k]+(t[i]-t[k]+m)^2

    f[j]+t[i]^2-2*t[i]*(t[j]+m)+(t[j]+m)^2<f[k]+t[i]^2-2*t[i]*(t[k]+m)+(t[k]+m)^2
    f[j]-2*t[i]*t[j]+t[j]^2+2*m*t[j]<f[k]-2*t[i]*t[k]+t[k]^2+2*m*t[k]
    f[j]-t[j]*2*(t[i]-m)+t[j]^2<f[k]-t[k]*2*(t[i]-m)+t[k]^2
    2*(t[i]-m)*(t[k]-t[j])<f[k]+t[k]^2-f[j]-t[j]^2
    ((f[k]+t[k]^2)-(f[j]+t[j]^2))/(t[k]-t[j])>2*(t[i]-m)
    这样就得到了一个斜率yi=f[i]+t[i]^2 xi=t[i]
     所以我们维护一个单调队列,单调性是两个相邻的数的斜率单调递增,即一个下凸壳。
    每次开始时,我们先把从队头开始斜率小于等于2*(t[i]-m)的删除,原因是如果满足此条件,那么q[t]必然没有q[t+1]优。
    #include<cstdio>
    typedef long long ll;
    const int N=50005;
    ll f[N],t[N];
    int q[N];
    double qz(int a,int b)
    {
        return (double)(f[a]+t[a]*t[a]-f[b]-t[b]*t[b])/(t[a]-t[b]);
    }
    int main()
    {
        int n,tt=0,ww=0;
        ll m;
        scanf("%d%lld",&n,&m);++m;
        for(int i=1;i<=n;i++) scanf("%lld",&t[i]),t[i]+=t[i-1];
        for(int i=1;i<=n;i++) t[i]+=i;
        for(int i=1;i<=n;i++)
        {
            double xl=2*(t[i]-m);
            for(;tt<ww&&qz(q[tt],q[tt+1])<=xl;tt++);
            f[i]=f[q[tt]]+(t[i]-t[q[tt]]-m)*(t[i]-t[q[tt]]-m);
            for(;tt<ww&&qz(q[ww],q[ww-1])>=qz(q[ww],i);ww--);
            q[++ww]=i;
        }
        printf("%lld",f[n]);
        return 0;
    }
  • 相关阅读:
    Yield Usage Understanding
    Deadclock on calling async methond
    How to generate file name according to datetime in bat command
    Run Unit API Testing Which Was Distributed To Multiple Test Agents
    druid的关键参数+数据库连接池运行原理
    修改idea打开新窗口的默认配置
    spring boot -thymeleaf-url
    @pathvariable和@RequestParam的区别
    spring boot -thymeleaf-域对象操作
    spring boot -thymeleaf-遍历list和map
  • 原文地址:https://www.cnblogs.com/bzmd/p/6266588.html
Copyright © 2020-2023  润新知