码迷,mamicode.com
首页 > 其他好文 > 详细

[ZJOI2007] 仓库建设

时间:2019-02-10 23:42:05      阅读:345      评论:0      收藏:0      [点我收藏+]

标签:read   turn   getch   复杂度   max   算法   oid   nbsp   ==   

[题目链接]

          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\n" , ans);
    
    return 0;
}

 

[ZJOI2007] 仓库建设

标签:read   turn   getch   复杂度   max   算法   oid   nbsp   ==   

原文地址:https://www.cnblogs.com/evenbao/p/10360317.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!