【斜率优化】仓库建设(luogu 2120)
倉庫建設(shè)
luogu 2120
題目大意
有一個斜坡,上面有n個工廠(山頂是1,山腳是nnn,工廠都是漏填),上面有pip_ipi?個貨物,和工廠1的距離為x1x_1x1?
現(xiàn)在有一場大雨,你可以在某些工廠處建立倉庫(費用是cic_ici?),沒有建立倉庫的工廠要把貨物運到更低的倉庫(及編號越大的倉庫),運費是貨物數(shù)?*?距離
現(xiàn)在問你全部貨物運到倉庫中最少需要多少錢
輸入樣例
3 0 5 10 5 3 100 9 6 10輸出樣例
32樣例說明
在工廠 1 和工廠 3 建立倉庫,建立費用為 10+10=2010+10=2010+10=20 ,運輸費用為 (9?5)×3=12(9-5) \times 3 = 12(9?5)×3=12,總費用 32。
數(shù)據(jù)范圍
對于 20%20\%20% 的數(shù)據(jù),保證 n≤500n \leq 500n≤500。
對于 40%40\%40% 的數(shù)據(jù),保證 n≤104n \leq 10^4n≤104 。
對于 100%100\%100% 的數(shù)據(jù),保證 1≤n≤1061 \leq n \leq 10^61≤n≤106 ,0≤xi,pi,ci<2310 \leq x_i,~p_i,~c_i < 2^{31}0≤xi?,?pi?,?ci?<231 。
對于任意的 1≤i<n1 \leq i < n1≤i<n,保證 xi<xi+1。x_i < x_{i + 1} 。xi?<xi+1?。
設(shè)答案為 ansansans,保證 ans+∑i=1npixi<263ans + \sum_{i = 1}^{n} p_ix_i < 2^{63}ans+∑i=1n?pi?xi?<263 。
解題思路
我們設(shè)fif_ifi?為在iii處建倉庫,前iii個工廠的貨物全部運到倉庫的最小費用(這里把ppp改為sss,把xxx改為vvv)
我們就可以得出轉(zhuǎn)移方程
fi=min?{fj+ci+∑k=j+1i?1(vi?vk)sk}=min?{fj+ci+∑k=j+1i(vi?vk)sk}=min?{fj+ci+∑k=j+1ivisk?∑k=j+1ivksk}=min?{fj+ci+(sumsi?sumsj)vi?(vsi?vsj)}\begin{aligned}f_i & = \min\{f_j+c_i+\sum_{k=j+1}^{i-1}(v_i-v_k)s_k\} \\ & = \min\{f_j+c_i+\sum_{k=j+1}^{i}(v_i-v_k)s_k\} \\ & =\min\{f_j+c_i+\sum_{k=j+1}^{i}v_is_k-\sum_{k=j+1}^{i}v_ks_k\} \\ & = \min\{f_j + c_i + (sums_i-sums_j)v_i - (vs_i - vs_j)\} \end{aligned}fi??=min{fj?+ci?+k=j+1∑i?1?(vi??vk?)sk?}=min{fj?+ci?+k=j+1∑i?(vi??vk?)sk?}=min{fj?+ci?+k=j+1∑i?vi?sk??k=j+1∑i?vk?sk?}=min{fj?+ci?+(sumsi??sumsj?)vi??(vsi??vsj?)}?
注:
第二行加了iii這一項,但因為vi?vi=0v_i-v_i=0vi??vi?=0所以結(jié)果不變
第四行vsi=∑j=1ivisivs_i=\sum_{j=1}^{i} v_is_ivsi?=∑j=1i?vi?si?
若現(xiàn)在有兩個決策點a,ba,ba,b滿足a>b,aa>b,aa>b,a優(yōu)于bbb
則:
fa+ci+(sumsi?sumsa)vi?(vsi?vsa)<fb+ci+(sumsi?sumsb)vi?(vsi?vsb)f_a + c_i + (sums_i-sums_a)v_i - (vs_i - vs_a) < f_b + c_i + (sums_i-sums_b)v_i - (vs_i - vs_b)fa?+ci?+(sumsi??sumsa?)vi??(vsi??vsa?)<fb?+ci?+(sumsi??sumsb?)vi??(vsi??vsb?)
fa+ci+sumsivi?sumsavi?vsi+vsa<fb+ci+sumsivi?sumsbvi?vsi+vsbf_a + c_i + sums_iv_i-sums_av_i - vs_i + vs_a < f_b + c_i + sums_iv_i-sums_bv_i - vs_i + vs_bfa?+ci?+sumsi?vi??sumsa?vi??vsi?+vsa?<fb?+ci?+sumsi?vi??sumsb?vi??vsi?+vsb?
fa?sumsavi+vsa<fb?sumsbvi+vsbf_a-sums_av_i + vs_a < f_b-sums_bv_i + vs_bfa??sumsa?vi?+vsa?<fb??sumsb?vi?+vsb?
(fa+vsa)?(fb+vsb)<sumsavi?sumsbvi(f_a+vs_a)-(f_b+vs_b)< sums_av_i-sums_bv_i(fa?+vsa?)?(fb?+vsb?)<sumsa?vi??sumsb?vi?
(fa+vsa)?(fb+vsb)<sumsavi?sumsbvi(f_a+vs_a)-(f_b+vs_b)< sums_av_i-sums_bv_i(fa?+vsa?)?(fb?+vsb?)<sumsa?vi??sumsb?vi?
((fa+vsa)?(fb+vsb))/(sumsa?sumsb)<vi((f_a+vs_a)-(f_b+vs_b))/(sums_a-sums_b)<v_i((fa?+vsa?)?(fb?+vsb?))/(sumsa??sumsb?)<vi?
我們設(shè)
yi=fi+vsay_i=f_i+vs_ayi?=fi?+vsa?
xi=sumsix_i=sums_ixi?=sumsi?
則
(ya?yb)/(xa?xb)<vi(y_a-y_b)/(x_a-x_b)<v_i(ya??yb?)/(xa??xb?)<vi?
然后按照斜率優(yōu)化模板套即可
代碼
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; ll n, l, r, v[1000050], s[1000050], c[1000050], d[1000050], y[1000050], f[1000050], vs[1000050]; int main() {scanf("%d", &n);for (int i = 1; i <= n; ++i){scanf("%d%d%d", &v[i], &s[i], &c[i]);vs[i] = vs[i - 1] + v[i] * s[i];s[i] += s[i - 1];//s沒用,就直接弄成前綴和}for (int i = 1; i <= n; ++i){while(r > l && (y[d[l + 1]] - y[d[l]]) < v[i] * (s[d[l + 1]] - s[d[l]])) l++;//模板f[i] = f[d[l]] + c[i] + (s[i] - s[d[l]]) * v[i] - (vs[i] - vs[d[l]]);y[i] = f[i] + vs[i];while(r > l && (y[i] - y[d[r]])*(s[d[r]] - s[d[r-1]]) < (y[d[r]] - y[d[r-1]])*(s[i] - s[d[r]])) r--;d[++r] = i;}printf("%d", f[n]);return 0; }總結(jié)
以上是生活随笔為你收集整理的【斜率优化】仓库建设(luogu 2120)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 春节的来历简短最佳答案 春节的来历看这里
- 下一篇: 幸福感城市排名2019 2019年中国最