【斜率优化】玩具装箱(luogu 3195)
玩具裝箱
luogu 3195
題目大意
有n件物品,每件物品有相對的長度CiC_iCi?現在要把這n件物品放到容器中,切放的物品必須是連續的,若把第i件物品到第j件物品放到一個容器中,那此容器的長度定義為x=j?i+∑k=ijCix=j?i+\sum_{k=i}^{j} C_ix=j?i+∑k=ij?Ci?,此容器的費用即為(x?L)2(x-L)^2(x?L)2(L是常數),現在問你把所有物品放倒容器中,費用之和最小是多少
輸入樣例
5 4 3 4 2 1 4輸出樣例
1數據范圍
對于全部的測試點,1≤n≤5×1041 \leq n \leq 5 \times 10^41≤n≤5×104,1≤L≤1071 \leq L \leq 10^71≤L≤107,1≤Ci≤1071 \leq C_i \leq 10^71≤Ci?≤107。
解題思路
我們設f[i]為把1至i的所有物品放進容器中的最小費用,那我們可以得出轉移方程:
fi=fj+(i?(j+1)+sumi?sumj?L)2f_i=f_j+(i-(j+1)+sum_i-sum_j-L)^2fi?=fj?+(i?(j+1)+sumi??sumj??L)2
注:sum是C的前綴和,這個范圍是j+1到i所以減的是j+1,前綴和減的是sum[(j+1)-1]
但是會超時間,所以我們要考慮優化
我們可以變式為:
fi=fj+((i+sumi?1?L)?(j+sumj))2f_i=f_j+((i+sum_i-1-L)-(j+sum_j))^2fi?=fj?+((i+sumi??1?L)?(j+sumj?))2
然后把平方拆開,得到:
fi=fj+(i+sumi?1?L)2?2?(i+sumi?1?L)?(j+sumj)+(j+sumj)2f_i=f_j+(i+sum_i-1-L)^2-2*(i+sum_i-1-L)*(j+sum_j)+(j+sum_j)^2fi?=fj?+(i+sumi??1?L)2?2?(i+sumi??1?L)?(j+sumj?)+(j+sumj?)2
若有決策點a,b滿足a>b且a比b優
則
fa+(i+sumi?1?L)2?2?(i+sumi?1?L)?(a+suma)+(a+suma)2<fj+(i+sumi?1?L)2?2?(i+sumi?1?L)?(b+sumb)+(b+sumb)2f_a+(i+sum_i-1-L)^2-2*(i+sum_i-1-L)*(a+sum_a)+(a+sum_a)^2<f_j+(i+sum_i-1-L)^2-2*(i+sum_i-1-L)*(b+sum_b)+(b+sum_b)^2fa?+(i+sumi??1?L)2?2?(i+sumi??1?L)?(a+suma?)+(a+suma?)2<fj?+(i+sumi??1?L)2?2?(i+sumi??1?L)?(b+sumb?)+(b+sumb?)2
變式
fa?2?(i+sumi?1?L)?(a+suma)+(a+suma)2<fj?2?(i+sumi?1?L)?(b+sumb)+(b+sumb)2f_a-2*(i+sum_i-1-L)*(a+sum_a)+(a+sum_a)^2<f_j-2*(i+sum_i-1-L)*(b+sum_b)+(b+sum_b)^2fa??2?(i+sumi??1?L)?(a+suma?)+(a+suma?)2<fj??2?(i+sumi??1?L)?(b+sumb?)+(b+sumb?)2
(fa+(a+suma)2)?(fb+(b+sumb)2)<2?(i+sumi?1?L)?((a+suma)?(b+sumb))(f_a+(a+sum_a)^2) - (f_b+(b+sum_b)^2)<2*(i+sum_i-1-L)*((a+sum_a)-(b+sum_b))(fa?+(a+suma?)2)?(fb?+(b+sumb?)2)<2?(i+sumi??1?L)?((a+suma?)?(b+sumb?))
((fa+(a+suma)2)?(fb+(b+sumb)2))/((a+suma)?(b+sumb))<2?(i+sumi?1?L)((f_a+(a+sum_a)^2) - (f_b+(b+sum_b)^2))/((a+sum_a)-(b+sum_b))<2*(i+sum_i-1-L)((fa?+(a+suma?)2)?(fb?+(b+sumb?)2))/((a+suma?)?(b+sumb?))<2?(i+sumi??1?L)
設
xi=i+sumix_i=i+sum_ixi?=i+sumi?
yi=fi+(i+sumi)2y_i=f_i+(i+sum_i)^2yi?=fi?+(i+sumi?)2
則
(ya?yb)/(xa?xb)<2?(i+sumi?1?L)(y_a - y_b)/(x_a-x_b)< 2*(i+sum_i-1-L)(ya??yb?)/(xa??xb?)<2?(i+sumi??1?L)
帶入模板即可
代碼
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long using namespace std; ll n, L, l, r, a[50010], sum[50010], x[50010], y[50010], q[50010], f[50010]; int main() {scanf("%lld %lld", &n, &L);for (ll i = 1; i <= n; ++i){scanf("%lld", &a[i]);sum[i] = sum[i - 1] + a[i];x[i] = sum[i] + i;}memset(f, 127/3, sizeof(f));f[0] = 0;q[1] = 0;l = 1;r = 1;for (ll i = 1; i <= n; ++i){while(l < r && (y[q[l + 1]] - y[q[l]]) <= 2 * (x[i] - 1 - L) * (x[q[l + 1]] - x[q[l]]))l++;//模板f[i] = f[q[l]] + (x[i] - x[q[l]] - 1 - L) * (x[i] - x[q[l]] - 1 - L);y[i] = f[i] + x[i] * x[i];while(l < r && (y[q[r]] - y[q[r - 1]]) * (x[i] - x[q[r]]) >= (y[i] - y[q[r]]) * (x[q[r]] - x[q[r - 1]])) r--;q[++r] = i;}printf("%lld", f[n]);return 0; }總結
以上是生活随笔為你收集整理的【斜率优化】玩具装箱(luogu 3195)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 暗黑破坏神3难度调整不了 进来看看
- 下一篇: 趋势科技云安全软件怎么清理垃圾