zoukankan      html  css  js  c++  java
  • BZOJ 1096: [ZJOI2007]仓库建设( dp + 斜率优化 )

     dp(v) = min(dp(p)+cost(p,v))+C(v)

    设sum(v) = ∑pi(1≤i≤v), cnt(v) = ∑pi*xi(1≤i≤v),

    则cost(p,v) = x(v)*(sum(v)-sum(p)) - (cnt(v)-cnt(p))

    假设dp(v)由dp(i)转移比dp(j)转移优(i>j),

    那么  dp(i)+cost(i,v) < dp(j)+cost(j,v)

    即 dp(i)+x(v)*(sum(v)-sum(i))-(cnt(v)-cnt(i)) < dp(j)+x(v)*(sum(v)-sum(j))-(cnt(v)-cnt(j))

    设f(x) = dp(x)+cnt(x), 化简得 (f(i)-f(j)) / (sum(i)-sum(j)) < x(v)

    然后就斜率优化, 单调队列维护一个下凸函数

    -----------------------------------------------------------------------

    #include<bits/stdc++.h>
     
    using namespace std;
     
    typedef long long ll;
     
    const int maxn = 1000009;
     
    ll sum[maxn], cnt[maxn], dp[maxn];
    int x[maxn], N, Q[maxn];
     
    inline double slope(int a, int b) {
    return (double) (dp[b] + cnt[b] - dp[a] - cnt[a]) / (sum[b] - sum[a]);
    }
     
    int main() {
    scanf("%d", &N);
    dp[0] = cnt[0] = sum[0] = 0;
    for(int i = 1; i <= N; i++) {
    int p; scanf("%d%d%lld", x + i, &p, dp + i);
    sum[i] = sum[i - 1] + p;
    cnt[i] = cnt[i - 1] + ll(p) * x[i];
    }
    int qh = 0, qt = 1; Q[0] = 0; // Q [qh, qt)
    for(int i = 1; i <= N; i++) {
    while(qt - qh > 1 && slope(Q[qh], Q[qh + 1]) < x[i]) qh++;
    int best = Q[qh];
    dp[i] += dp[best] + ll(x[i]) * (sum[i] - sum[best]) - cnt[i] + cnt[best];
    while(qt - qh > 1 && slope(Q[qt - 2], Q[qt - 1]) >= slope(Q[qt - 1], i)) qt--;
    Q[qt++] = i;
    }
    printf("%lld ", dp[N]);
    return 0;
    }

    ----------------------------------------------------------------------- 

    1096: [ZJOI2007]仓库建设

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 3001  Solved: 1286
    [Submit][Status][Discuss]

    Description

    L公司有N个工厂,由高到底分布在一座山上。如图所示,工厂1在山顶,工厂N在山脚。 由于这座山处于高原内陆地区(干燥少雨),L公司一般把产品直接堆放在露天,以节省费用。突然有一天,L公司的总裁L先生接到气象部门的电话,被告知三天之后将有一场暴雨,于是L先生决定紧急在某些工厂建立一些仓库以免产品被淋坏。由于地形的不同,在不同工厂建立仓库的费用可能是不同的。第i个工厂目前已有成品Pi件,在第i个工厂位置建立仓库的费用是Ci。对于没有建立仓库的工厂,其产品应被运往其他的仓库进行储藏,而由于L公司产品的对外销售处设置在山脚的工厂N,故产品只能往山下运(即只能运往编号更大的工厂的仓库),当然运送产品也是需要费用的,假设一件产品运送1个单位距离的费用是1。假设建立的仓库容量都都是足够大的,可以容下所有的产品。你将得到以下数据: 工厂i距离工厂1的距离Xi(其中X1=0);  工厂i目前已有成品数量Pi;  在工厂i建立仓库的费用Ci; 请你帮助L公司寻找一个仓库建设的方案,使得总的费用(建造费用+运输费用)最小。

    Input

    第一行包含一个整数N,表示工厂的个数。接下来N行每行包含两个整数Xi, Pi, Ci, 意义如题中所述。

    Output

    仅包含一个整数,为可以找到最优方案的费用。

    Sample Input

    3
    0 5 10
    5 3 100
    9 6 10

    Sample Output

    32

    HINT

    在工厂1和工厂3建立仓库,建立费用为10+10=20,运输费用为(9-5)*3 = 12,总费用32。如果仅在工厂3建立仓库,建立费用为10,运输费用为(9-0)*5+(9-5)*3=57,总费用67,不如前者优。

    【数据规模】

    对于100%的数据, N ≤1000000。 所有的Xi, Pi, Ci均在32位带符号整数以内,保证中间计算结果不超过64位带符号整数。 

    Source

  • 相关阅读:
    个人冲刺二(7)
    个人冲刺二(6)
    个人冲刺二(5)
    个人冲刺二(4)
    对称二叉树 · symmetric binary tree
    108 Convert Sorted Array to Binary Search Tree数组变成高度平衡的二叉树
    530.Minimum Absolute Difference in BST 二叉搜索树中的最小差的绝对值
    pp 集成工程师 mism师兄问一问
    17. Merge Two Binary Trees 融合二叉树
    270. Closest Binary Search Tree Value 二叉搜索树中,距离目标值最近的节点
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4781025.html
Copyright © 2011-2022 走看看