zoukankan      html  css  js  c++  java
  • HNOI 2008 玩具装箱toy(DP + 斜率优化)

    题意:

    有一堆玩具可以压缩成 Ci 长度,放在容器中,同时一个容器内玩具的编号必须是连续的,每个容器所需要的费用题目中给了,求最小费用。

    思路:

    1. 网上推导的代码啰里啰嗦的,完全没有理解清楚不变量 i 的真谛,从而对于平方的展开添加了很多不必要的麻烦。

    2. dp[i] 表示拿到第 i 件玩具时,所需要的最小费用。当 i 和前面的 x 件连着时,才有有递推式:dp[i] = dp[j] + (i-j-1 + Ci-Cj + L)2;

    3. 对平方里面的因式进行必要的化简:S[i] = i + Ci; 于是 dp[i] = dp[j] + (Si - Sj + L - 1)2;

    4. 再进行精简,令 m = Si + L - 1; dp[i] = dp[j] + (m - Sj)= dp[j] + m2 - 2*m*Sj + Sj2;

    5. 利用斜率优化,此时有 X = Sj, Y = dp[j] + Sj2, a = 2*m;  a 满足递增的特性,求 dp[i] 最小。根据下凸函数的特性,利用队列对其进行优化即可,O(N);

    6. 要注意的一个边界是 :当 i 固定, j 可能取 0 时使结果最优,所以对于 0 要提前入队,这样得到总体最优解。

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    using namespace std;
     
    #define LL long long int
     
    const int MAXN = 50010;
     
    int deq[MAXN];
    LL C[MAXN], S[MAXN], dp[MAXN];
     
    inline double slope(int i, int j)
    {
        return 1.0 * (dp[i] + S[i] * S[i] - dp[j] - S[j] * S[j]) / (S[i] - S[j]);
    }
     
    int main()
    {
        int N, L;
        while (scanf("%d %d", &N, &L) != EOF)
        {
            C[0] = S[0] = 0;
            for (int i = 1; i <= N; ++i)
            {
                scanf("%lld", &C[i]);
                C[i] += C[i-1], S[i] = i + C[i];
            }
     
            int s = 0, e = 0;
            dp[0] = deq[s] = 0;
            for (int i = 1; i <= N; ++i)
            {
                LL m = S[i] - L - 1;
     
                while (s < e && slope(deq[s+1], deq[s]) <= 2 * m)
                    ++s;
     
                int j = deq[s];
                dp[i] = dp[j] + (m - S[j]) * (m - S[j]);
     
                while (s < e && slope(deq[e], deq[e-1]) >= slope(i, deq[e]))
                    --e;
                deq[++e] = i;
            }
            printf("%lld\n", dp[N]);
        }
        return 0;
    }
  • 相关阅读:
    docker-compose
    获取时区
    maven插件
    jquery_ui_api中文
    sax xpath读取xml字符串
    Ant打包
    [转]html5音乐播放器
    javax mail网址
    vbscript调用fso
    fso查找被删除的文件
  • 原文地址:https://www.cnblogs.com/kedebug/p/2941359.html
Copyright © 2011-2022 走看看