• bzoj1010[HNOI2008]玩具装箱toy


    1010: [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

    一道很好的练习斜率优化的题目 (大家都这么说~~)

    dp 方程很容易看出 令 sum[i] = $sum_1^j C[j]$

    $f[i] = min(f[i], f[j] + (sum[i] - sum[j] + i - j - 1 - L) ^ 2)$

    我们来对上面的式子进行化简

    令s[i] = sum[i] + i

    所以$f[i] = f[j] + (s[i] - s[j] - (L +1) ^ 2)$

                $= f[j] + s[i] ^ 2 - 2 * s[i] * (s[j] + L + 1) + (s[j] + L + 1) ^ 2$

    我们进行一下移项

    $f[j] + (s[j] + L + 1) ^ 2 = s[i] * 2 * (s[j] + L + 1) + (f[i] - s[i] ^ 2)$

    于是这个式子就变为了 y = kx + b 的形式

    即$ y = f[j] + (s[j] + L + 1) ^ 2, k = s[i], x = 2 * (s[j] + L + 1) , b = f[i] - s[i]^2$

    我们可以设点$j = (2 * (s[j] + L + 1), f[j] + (s[j] + L + 1) ^ 2)$

    那么原来从j 到 i 的转移方程就变为了已知点j 和斜率 s[i], f[i]即为截距

    而因为s[i] 是单调递增的,我们便可以用一个单调队列来维护

    假设这是我们现有的队列中对应的凸包

    当我们要更新i时

    对应直线斜率是s[i]

    可以想象, 如果凸包最前面的直线的斜率是小于s[i]的,那么左边的点对应的截距也会大,因此我们可以将对首的点弹出

    当f[i]更新后,我们要将i点放入凸包中

    就用同样的查找凸包操作,从队尾弹出即可

     

    我写的时候因为把 dp 数组设为了 long long 结果就炸了精度,调了老半天,一定小心 TAT!!

     1 #include <iostream>
     2 #include <cstdio>
     3 #include <algorithm>
     4 #include <cstring>
     5 #define LL long long
     6 
     7 using namespace std;
     8 
     9 const int MAXN = 1e5 + 10;
    10 LL N;
    11 double L;
    12 double sum[MAXN];
    13 double s[MAXN];
    14 double f[MAXN];
    15 LL c[MAXN];
    16 int q[MAXN];
    17 int head = 0, tail = 0;
    18 struct node {
    19     double y;
    20     double x;
    21 } t[MAXN];
    22 inline LL read()
    23 {
    24     LL x = 0, w = 1; char ch = 0;
    25     while(ch < '0' || ch > '9') {
    26         if(ch == '-') {
    27             w = -1;
    28         }
    29         ch = getchar();
    30     }
    31     while(ch >= '0' && ch <= '9') {
    32         x = x * 10 + ch - '0';
    33         ch = getchar();
    34     }
    35     return x * w;
    36 }
    37 
    38 double cal(int a, int b)
    39 {
    40     return (t[a].y - t[b].y) / (t[a].x - t[b].x);    
    41 }
    42 int main()
    43 {
    44     memset(f, 0x3f, sizeof f);
    45     f[0] = 0;
    46     N = read(), L = read();
    47     for(int i = 1; i <= N; i++) {
    48         c[i] = read();
    49         sum[i] = sum[i - 1] + c[i];
    50         s[i] = sum[i] + i;
    51     }
    52     memset(f, 0x3f, sizeof f);
    53     f[0] = 0;
    54     t[0].x = 2 * (L + 1);
    55     t[0].y = (L + 1) * (L + 1);
    56 //    cout<<t[0].x<<" "<<t[0].y<<endl;
    57     tail = 1;
    58     q[0] = 0;
    59     for(int i = 1; i <= N; i++) {
    60         while(head + 1 < tail && cal(q[head], q[head + 1]) <= s[i]) {
    61             head++;
    62         }
    63         int j = q[head];
    64         f[i] = f[j] + (s[i] - s[j] - (L + 1)) * (s[i] - s[j] - (L + 1));
    65         t[i].x = 2 * (s[i] + L + 1);
    66         t[i].y = f[i] + (s[i] + L + 1) * (s[i] + L + 1); 
    67         while(tail > head + 1 && cal(q[tail - 1], i) < cal(q[tail - 1], q[tail - 2])) {
    68             tail--;
    69         }
    70         q[tail++] = i; 
    71     }
    72     printf("%lld
    ", (LL)f[N]);
    73     return 0;
    74 }
    75 
    76 /*
    77 5 4
    78 
    79 3
    80 
    81 4
    82 
    83 2
    84 
    85 1
    86 
    87 4
    88 */
    View Code
  • 相关阅读:
    jQuery里$.post请求,后台返回结果为“json”格式,前台解析错误问题记录
    传真机传真外地拨号后提示号码不正确问题
    web.xml里,classpath使用范围
    几种排序的算法
    随机红包
    python小练习
    unitest
    自动化测试模型
    WebDriver API
    Android monkey
  • 原文地址:https://www.cnblogs.com/wuenze/p/8399088.html
Copyright © 2020-2023  润新知