HNOI2008 玩具裝箱TOY

2021-10-01 17:54:13 字數 3843 閱讀 1030

題目鏈結

學過斜率優化的同學應該知道只是一道板子題,這裡我們給出乙個不同的解法:

我們定義f[i

]f[i]

f[i]

表示考慮到了第i

ii個點的最小代價是多少,那麼我們可以得出這個轉移式子:

f [i

]=mi

nj=1

i(f[

j]+w

[j][

i]

)f[i]=min_^i(f[j]+w[j][i])

f[i]=m

inj=

1i​(

f[j]

+w[j

][i]

) 其中w [j

][i]

=(j−

i+∑k

=1jc

[k]−

l)

2w[j][i]=(j-i+\sum_^j c[k]-l)^2

w[j][i

]=(j

−i+∑

k=1j

​c[k

]−l)

2看著像不太好優化的樣子,但是實際上我們發現f[i

]f[i]

f[i]

是凸的,換句話說f[i

]f[i]

f[i]

的決策點具有單調性。

這樣我們考慮如果我們已經知道了乙個狀態f[i

]f[i]

f[i]

,我們考慮它能更新哪些狀態,不難發現,由於決策點具有單調性,那麼我們可以二分一下它所影響的區間,具體我們畫圖來解釋一下:

一開始所有點的最優決策點:

1111111111111111111111111111111111111111111111111

1111111111111111111111111111111111111111111111111

111111

1111

1111

1111

1111

1111

1111

1111

1111

1111

1111

111

顯然f [2

]f[2]

f[2]

的決策點是1

11,我們考慮2

22這個決策點能影響的範圍:

1111111111111111111111111112222222222222222222

1111111111111111111111111112222222222222222222

111111

1111

1111

1111

1111

1111

1222

2222

2222

2222

2222

接著我們考慮3

33,由於決策點具有單調性,那麼一定是這樣的:

1111111111111111111111111112222222233333333333

1111111111111111111111111112222222233333333333

111111

1111

1111

1111

1111

1111

1222

2222

2333

3333

3333

或者是:

1111111111111111111111111113333333333333333333

1111111111111111111111111113333333333333333333

111111

1111

1111

1111

1111

1111

1333

3333

3333

3333

3333

於是我們可以考慮維護乙個棧,每個元素(i,

j)

(i,j)

(i,j

)是乙個二元組,分別代表區間的左端點和它的決策點是什麼,考慮加入乙個數:

如果棧頂元素的左端點(原決策點)比現在的決策點更劣,那麼我們將這個區間全部捨棄,否則我們就在這個區間二分出改變的點,修改兩個元素即可。

考慮到每乙個決策點只會入棧和出棧一次,但是由於二分的存在,總複雜度是o(n

logn

)o(nlogn)

o(nlog

n)的。**實現:

//optimize

#pragma gcc optimize("ofast")

//head file

#include

using

namespace std;

#define il inline

//variable

#define ll long long

#define ull unsigned long long

#define db double

#define lb long double

//debug

#define b cerr<<"break point"<#define p(x) cerr<<#x<<' '<<"="<<' '<<(x)<#define p(x) cerr<<#x<<' '<<"="<<' '<<(x)<<' ';

#define ml(x) cerr<<"size of array is "#define vc vector

#define pub push_back

#define pob pop_back

#define vbe(x) x.begin(),x.end()

//memset

#define ms(x) memset(x,0,sizeof(x))

#define ms(x) memset(x,0x3f3f3f3f,sizeof(x))

//pair

#define fi first

#define se second

//file

#define fin(x) freopen(x,"r",stdin)

#define fou(x) freopen(x,"w",stdout)

void

fio(

)void

pti(

)void

end(

)//inf

#define inf 0x3f3f3f3f

#define linf ((long long)(0x3f3f3f3f3f3f3f3f))

//io

namespace io

while

(isdigit

(ch))w*

=op;

}template

<

class

i>

il void

print

(i w)

}using io::gi;

using io::print;

const

int n=

5e4+5;

struct node

;int n,top,stk[n]

,anc[n]

;ll l,c[n]

,f[n]

,pre[n]

;ll calc

(int fa,

int x)

intfind

(int x)

return l;

}int

main()

print

(f[n]);

end();

}

HNOI2008 玩具裝箱toy

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

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教授要求在乙個一維容器中的玩具編號是連續的。同時...