• [ZJOI2007] 仓库建设


    [题目链接]

              https://www.lydsy.com/JudgeOnline/problem.php?id=1096

    [算法]

           斜率优化

           时间复杂度 : O(N)

    [代码]

            

    #include<bits/stdc++.h>
    using namespace std;
    #define N 1000010
    typedef long long ll;
    typedef long double ld;
    typedef unsigned long long ull;
    
    int n , l , r;
    ll ans , totsum;
    int q[N];
    ll a[N] , cst[N] , pref[N] , suf[N] , f[N] , dis[N] , X[N] , Y[N];
    
    template <typename T> inline void chkmin(T &x , T y) { x = min(x , y); }
    template <typename T> inline void chkmax(T &x , T y) { x = max(x , y); }
    template <typename T> inline void read(T &x)
    {
       T f = 1; x = 0;
       char c = getchar();
       for (; !isdigit(c); c = getchar()) if (c == '-') f = -f;
       for (; isdigit(c); c = getchar()) x = (x << 3) + (x << 1) + c - '0';
       x *= f;
    }
    
    int main()
    {
        
        read(n);
        for (int i = 1; i <= n; i++)
        {
            read(dis[i]);
            read(a[i]);
            read(cst[i]);
        }
        totsum = cst[n];
        for (int i = 1; i <= n; i++)
        {
            suf[i] = dis[n] - dis[i];
            pref[i] = pref[i - 1] + a[i];
            totsum += suf[i] * a[i]; 
        }
        // f0 = totsum
        // fi = min{ fj - (prefi - prefj) * sufi + csti }
        // fi = min{ fj - prefi * sufi + prefj * sufi + csti }
        //    fj = Yj , prefj = Xj
        // Yj = fi + prefi * sufi - Xj * sufi - csti}
        // Yj = -sufi * Xj + fi + prefi * sufi - csti
        
        X[0] = 0;
        f[0] = Y[0] = totsum;
        q[l = r = 1] = 0;
        ll ans = totsum;
        for (int i = 1; i <= n; i++)
        {
            // (Yql+1 - Yql) / (Xql+1 - Xql) <= k
            while (l < r && Y[q[l + 1]] - Y[q[l]] <= -suf[i] * (X[q[l + 1]] - X[q[l]])) ++l;
            f[i] = f[q[l]] - (pref[i] - pref[q[l]]) * suf[i] + cst[i];
            X[i] = pref[i];
            Y[i] = f[i];
            chkmin(ans , f[i]);
            // (Yi - Yqr) / (Xi - Xqr) <= (Yqr - Yqr-1) / (Xqr - Xqr-1)
            while (l < r && (Y[i] - Y[q[r]]) * (X[q[r]] - X[q[r - 1]]) <= (Y[q[r]] - Y[q[r - 1]]) * (X[i] - X[q[r]])) --r;
            q[++r] = i;
        }
        printf("%lld
    " , ans);
        
        return 0;
    }
  • 相关阅读:
    关于浏览器及系统的判断
    toggle与slideToggle
    安卓与ios的不同处理
    关于常用循环遍历获取数据
    docker
    Mysql
    rabbitMQ的使用转载
    Git命令行
    vue项目创建完整版
    redis操作(str.hash.list.set)
  • 原文地址:https://www.cnblogs.com/evenbao/p/10360317.html
Copyright © 2020-2023  润新知