[题解]P2120 [ZJOI2007] 仓库建设

思路

我们定义 dpi 表示运输前 i 个工厂,且在第 i 个位置建立仓库所消耗的最小代价。

那么,我们可以得出状态转移方程:

dpi=min(dpj+xi×(k=j+1ipk)k=j+1i(xk×pk)+ci)

然后用前缀和优化一下:

dpi=min(dpj+xi×(spispj)(sfisfj)+ci)

拆开括号得:

dpi=min(dpjxi×spj+sfj+xi×spisfi+ci)

如果 j2 的代价优于 j1,那么当且仅当满足以下条件:

dpj1xi×spj1+sfj1+xi×spisfi+ci>dpj2xi×spj2+sfj2+xi×spisfi+ci

化简得:

dpj1xi×spj1+sfj1>dpj2xi×spj2+sfj2

(dpj1+sfj1)(dpj2+sfj2)>xi×(spj1spj2)

xi<(dpj1+sfj1)(dpj2+sfj2)spj1spj2

不妨令:

  1. dpx+sfxY(x)
  2. spxX(x)
  3. xiK

那么有:

K<Y(j2)Y(j1)X(j2)X(j1)

然后因为 pi 有可能为 0,所以我们找答案时倒着找第一个 pi 不为 0 的下标 t,那么,答案就为 mintindpi

Code

#include <bits/stdc++.h>  
#define int long long  
#define re register  
  
using namespace std;  
  
const int N = 1e6 + 10,inf = 1e18 + 10;  
int n,hh = 1,tt = 1;  
int x[N],p[N],c[N],sp[N],sf[N],dp[N],q[N];  
  
inline int read(){  
    int r = 0,w = 1;  
    char c = getchar();  
    while (c < '0' || c > '9'){  
        if (c == '-') w = -1;  
        c = getchar();  
    }  
    while (c >= '0' && c <= '9'){  
        r = (r << 3) + (r << 1) + (c ^ 48);  
        c = getchar();  
    }  
    return r * w;  
}  
  
inline int K(int i){  
    return x[i];  
}  
  
inline int X(int i){  
    return sp[i];  
}  
  
inline int Y(int i){  
    return dp[i] + sf[i];  
}  
  
inline double sl(int i,int j){  
    return 1.0 * (Y(j) - Y(i)) / (X(j) - X(i));  
}  
  
signed main(){  
    n = read();  
    for (re int i = 1;i <= n;i++){  
        x[i] = read();  
        p[i] = read();  
        c[i] = read();  
        sp[i] = sp[i - 1] + p[i];  
        sf[i] = sf[i - 1] + x[i] * p[i];  
    }  
    for (re int i = 1;i <= n;i++){  
        while (hh < tt && K(i) >= sl(q[hh],q[hh + 1])) hh++;  
        int j = q[hh];  
        dp[i] = dp[j] + x[i] * (sp[i] - sp[j]) - (sf[i] - sf[j]) + c[i];  
        while (hh < tt && sl(q[tt],q[tt - 1]) >= sl(i,q[tt - 1])) tt--;  
        q[++tt] = i;  
    }  
    int t = n;  
    while (!p[t] && t) t--;  
    if (!t) puts("0");  
    else{  
        int ans = inf;  
        for (re int i = t;i <= n;i++) ans = min(ans,dp[i]);  
        printf("%lld",ans);  
    }  
    return 0;  
}  

作者:WaterSun

出处:https://www.cnblogs.com/WaterSun/p/18268792

版权:本作品采用「署名-非商业性使用-相同方式共享 4.0 国际」许可协议进行许可。

posted @   WBIKPS  阅读(13)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】
more_horiz
keyboard_arrow_up dark_mode palette
选择主题
点击右上角即可分享
微信分享提示