zoukankan      html  css  js  c++  java
  • [bzoj1010](HNOI2008)玩具装箱toy(动态规划+斜率优化+单调队列)

    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

    分析

         这已经是HNOI2008第三道dp了吧……

         首先我们还是要写出转移方程:$$f(i) = min_{0 leq j < i} { f(j) + (S(i) - S(j) - L - 1)^2 } $$

         其中$S(i) = sumlimits_{j =1}^i (C(j) + 1).$
    然后把方程转化一下:$$f(i) = (S(i) - L - 1)^2 + \ min_{0 leq j<i} {-2(S(i)-L-1)S(j) + f(j) + S(j)^2 }$$
    就可以设$2(S(i)-L-1)$为斜率,$S(j)和 f(j) + S(j)^2$分别为横纵坐标建立凸包进行斜率优化,复杂度$O(NlogN)$.
    最后可以发现每次对凸包进行二分查找时的斜率$2(S(i)-L-1)$是随i单调递增的……于是我们可以用单调队列优化到$O(n)$。

     1 /**************************************************************
     2     Problem: 1010
     3     User: AsmDef
     4     Language: C++
     5     Result: Accepted
     6     Time:76 ms
     7     Memory:2176 kb
     8 ****************************************************************/
     9  
    10 #include <cctype>
    11 #include <cstdio>
    12 using namespace std;
    13 template<typename T>inline void getd(T &x){
    14     char c = getchar(); bool minus = 0;
    15     while(!isdigit(c) && c != '-')c = getchar();
    16     if(c == '-')minus = 1, c = getchar();
    17     x = c - '0';
    18     while(isdigit(c = getchar()))x = x * 10 + c - '0';
    19     if(minus)x = -x;
    20 }
    21 /*========================================================*/
    22 typedef long long LL;
    23 const int maxn = 50003;
    24 int N, L, V[maxn], it1 = 0, it2 = 1;
    25 LL S, X[maxn], Y[maxn], f[maxn];
    26 #define cmp(x, y, j, k)
    27     (y<=Y[j])?1:((k<0)?0:((x-X[j])*(Y[j]-Y[k]) >= (X[j]-X[k])*(y-Y[j])))
    28   
    29 inline void insert(LL x, LL y){
    30     if(it2 <= it1+1){
    31         X[it2] = x, Y[it2] = y;
    32         ++it2;
    33         return;
    34     }
    35     while(it2 > it1 && cmp(x, y, it2-1, it2-2))--it2;
    36     X[it2] = x, Y[it2] = y;
    37     ++it2;
    38 }
    39 inline void dp(){
    40     int i;
    41     LL k, t, b1, b2, y;
    42     for(i = 1;i <= N;++i){
    43         S += V[i];
    44         t = S - L - 1, k = - t << 1;
    45         b2 = k * X[it1] + Y[it1];
    46         if(it2 - it1 <= 1){
    47             f[i] = t * t + b2;
    48             y = f[i] + S * S;
    49             insert(S, y);
    50             continue;
    51         }
    52         while(it1 + 1 < it2){
    53             b1 = b2, b2 = k * X[it1+1] + Y[it1+1];
    54             if(b1 >= b2)++it1;
    55             else break;
    56         }
    57         f[i] = t * t + k * X[it1] + Y[it1];
    58         y = f[i] + S * S;
    59         insert(S, y);
    60     }
    61     printf("%lld ", f[N]);
    62 }
    63 int main(){
    64     #if defined DEBUG
    65     freopen("test""r", stdin);
    66     #else
    67     //freopen("bzoj_1010.in", "r", stdin);
    68     //freopen("bzoj_1010.out", "w", stdout);
    69     #endif
    70     int i, C;
    71     getd(N), getd(L);
    72     for(i = 1;i <= N;++i)
    73         getd(C), V[i] = C + 1;
    74     dp();
    75     return 0;
    76 }
    单调队列dp

  • 相关阅读:
    数据库三大范式
    idea连接sqlite
    Javascript中==和===的区别
    手机商城项目(修饰技术)
    FastJSON、Gson、Jackson(简单了解使用)
    SiteMesh配置下载使用(简单介绍)
    html5中event获取data和class
    jsp的4个作用域区别( pageScope、requestScope、sessionScope、applicationScope)
    <jsp:include>和<%@include file=""%>的区别(简单了解)
    Check-Point-Security-Gateway-BYOL-R77.30-041.161
  • 原文地址:https://www.cnblogs.com/Asm-Definer/p/4368297.html
Copyright © 2011-2022 走看看