題目鏈結
學過斜率優化的同學應該知道只是一道板子題,這裡我們給出乙個不同的解法:
我們定義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
(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()
(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教授要求在乙個一維容器中的玩具編號是連續的。同時...