HNOI2008 玩具裝箱toy

2021-06-08 02:40:10 字數 2104 閱讀 4912

重點在講斜率優化

description

p教授要去看奧運,但是他捨不下他的玩具,於是他決定把所有的玩具運到北京。他使用自己的壓縮器進行壓縮,其可以將任意物品變成一堆,再放到一種特殊的一維容器中。p教授有編號為1...n的n件玩具,第i件玩具經過壓縮後變成一維長度為ci.為了方便整理,p教授要求在乙個一維容器中的玩具編號是連續的。同時如果乙個一維容器中有多個玩具,那麼兩件玩具之間要加入乙個單位長度的填充物,形式地說如果將第i件玩具到第j個玩具放到乙個容器中,那麼容器的長度將為 

x=j-i+sigma(ck) i<=k<=j 

製作容器的費用與容器的長度有關,根據教授研究,如果容器長度為x,其製作費用為(x-l)^2.其中l是乙個 

常量。p教授不關心容器的數目,他可以製作出任意長度的容器,甚至超過l。但他希望費用最小. 

input

第一行輸入兩個整數n,l.接下來n行輸入ci.1<=n<=50000,1<=l,ci<=10^7 

output

輸出最小費用 

5 4342

141dp先入腦

有乙個dp[i]:=min(dp[j]+(sum[i]-sum[j]+i-j-1-l)^2)

的基本思路

預處理可以得到

f[i]:=sum[i]+i

;令c=l+1

可以簡化方程:

dp[i]:=min(dp[j]+(f[i]-f[j]-c)^2))

明顯這個為o(n^2)的演算法,,要再簡化;

一維的dp可以想到

斜率優化

所謂斜率優化,個人的感悟就是:

當 i:1-->n j:1-->n的n^2迴圈時 可以簡化j的迴圈 把1~n依次入隊出隊,當i要選擇j時,先根據最優策略縮短佇列,再在選取隊首元素直接作為j,算出dp[i];

這樣做的話每個數進出一次佇列 複雜度就變為o(n);

但是這樣做必須證明單調性,也就是出隊的元素在以後的dp中不會再被利用

下面說說怎麼縮短佇列

dp[i]:=min(dp[j]+(f[i]-f[j]-c)^2))

中j的選擇是決定dp[i]的大小的 而 f[i]、c這樣的常量是不變的(對於同乙個i來說)

所以我們把不含j的變數分離出來,方便運算

dp[i]:=min(dp[j]+f[j]^2-2f[i]f[j]+2f[j]*c)+f[i]^2+c^2-2*f[i]*c;

假設選j好過選k, 

本題為

dp[j]+f[j]^2-2f[i]f[j]+2f[j]*c<

dp[k]+f[k]^2-2f[i]f[k]+2f[k]*c

化簡分離i

dp[j]-dp[k]+(f[i]-f[k])*(2c+f[j]+f[k])

-------------------------------------------

2(f[j]-f[k])

簡化其為

com(j,k)

也就是說 『選j好過選k』當且僅當『

com(j,k)成立』

所以如果乙個佇列的頭依次為a,b 如果g(b,a)<

=f[i] 那麼把a刪了吧

q[1]:=0;

head:=1;

tail:=1;

for i:=1 to n do

begin

while (head<=tail-1)and(com(q[head],q[head+1])<=sum[i]) do

inc(head);

dp[i]:=dp[q[head]]+(f[i]-f[q[head]]-l-1)*(f[i]-f[q[head]]-l-1);

while (head<=tail-1)and(com(q[tail-1],q[tail])>=com(q[tail],i)) do

dec(tail);

inc(tail);

q[tail]:=i;

end;

end;

這就是所謂的斜率優化  

HNOI2008 玩具裝箱toy

dp i min dp j sum i sum j c 2 dp k sum i sum k c 2 dp k si sum k 2 dp k si 2 2 si sum k sum k 2 dp k sum k 2 dp j sum j 2 2 si sum k sum j yk yj 2 si ...

HNOI2008 玩具裝箱TOY

題目描述 p教授要去看奧運,但是他捨不下他的玩具,於是他決定把所有的玩具運到北京。他使用自己的壓縮器進行壓縮,其可以將任意物品變成一堆,再放到一種特殊的一維容器中。p教授有編號為1 n的n件玩具,第i件玩具經過壓縮後變成一維長度為ci.為了方便整理,p教授要求在乙個一維容器中的玩具編號是連續的。同時...

HNOI2008 玩具裝箱TOY

這題可以說是斜率優化dp的模板題。首先,我們先推推它的dp式 f i min 這裡的c i 表示的是原來的c 1 i 的和 然後我們假設k我們可以將c i 再表示為c 1 i i,這樣就簡單很多了。改改dp式 f i min f j c i c j l 1 2 2我們用換元法,設x c j l 1,...