日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【斜率优化】玩具装箱(luogu 3195)

發布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【斜率优化】玩具装箱(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^41n5×1041≤L≤1071 \leq L \leq 10^71L1071≤Ci≤1071 \leq C_i \leq 10^71Ci?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)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。