• 【BZOJ 1010】 [HNOI2008]玩具装箱toy (斜率优化)


    1010: [HNOI2008]玩具装箱toy

    Time Limit: 1 Sec  Memory Limit: 162 MB
    Submit: 9330  Solved: 3739

    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
     
     
    【分析】
     
         f[i]=f[j]+(i-(j+1)+sum[i]-sum[j]-l)^2
        设d[i]=sum[i]+i,d[j]=sum[j]+j,L=l+1
      得 f[i]=f[j]+(d[i]-d[j]-L)^2
        =  (-2d[i]*d[j])+(f[j]+d[j]+2*d[j]*L)+(d[i]*d[i]-2*d[i]*L+L*L)
      得出斜率优化标准式子,因为都是正数,d[i]递增,动态维护一个下凸包即可。
     
    代码如下:
     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 #include<queue>
     7 #include<cmath>
     8 using namespace std;
     9 #define Maxn 50010
    10 #define LL long long
    11 
    12 LL c[Maxn],d[Maxn],f[Maxn];
    13 struct node
    14 {
    15     LL x,y;
    16 }t[Maxn];int len;
    17 
    18 LL n,l;
    19 
    20 void init()
    21 {
    22     scanf("%lld%lld",&n,&l);
    23     for(int i=1;i<=n;i++)
    24     {
    25         scanf("%lld",&c[i]);
    26         d[i]=d[i-1]+c[i]+1;
    27     }
    28     f[0]=0;d[0]=0;
    29     // f[1]=(c[1]-l)*(c[1]-l);
    30     l++;
    31 }
    32 
    33 bool check(int x,int y,LL k)
    34 {
    35     return (t[y].y-t[x].y)<=k*(t[y].x-t[x].x);
    36 }
    37 
    38 bool check2(int x,int y,int z)
    39 {
    40     return (t[z].y-t[y].y)*(t[y].x-t[x].x)<=(t[y].y-t[x].y)*(t[z].x-t[y].x);
    41 }
    42 
    43 void ffind()
    44 {
    45     len=0;int st=1;
    46     t[++len].x=0,t[len].y=0;
    47     for(int i=1;i<=n;i++)
    48     {
    49         while(st<len&&check(st,st+1,2*d[i])) st++;
    50         f[i]=-2*d[i]*t[st].x+t[st].y+d[i]*d[i]-2*d[i]*l+l*l;
    51         t[0].x=d[i];t[0].y=f[i]+d[i]*d[i]+2*d[i]*l;
    52         while(st<len&&check2(len-1,len,0)) 
    53             len--;
    54         t[++len]=t[0];
    55     }
    56     // for(int i=1;i<=n;i++) printf("%lld
    ",f[i]);
    57     printf("%lld
    ",f[n]);
    58 }
    59 
    60 int main()
    61 {
    62     init();
    63     ffind();
    64     return 0;
    65 }
    [BZOJ 1010]

    2016-09-16 16:53:22

     
  • 相关阅读:
    MySQL乱码问题
    Oracle安装错误“程序异常终止
    Hibernate Spring
    快学Scala 第一课 (变量,类型,操作符)
    Scala 学习笔记之隐式参数和隐式转换并用
    Hadoop 学习笔记之 Incompatible namespaceIDs问题
    Kafka 学习笔记之 Topic日志清理
    Zookeeper 学习笔记之 节点个数
    Kafka 学习笔记之 删除Topic
    Kafka 学习笔记之 架构
  • 原文地址:https://www.cnblogs.com/Konjakmoyu/p/5876684.html
Copyright © 2020-2023  润新知