p3195 [hnoi2008]玩具裝箱
一道比較模板的斜率優化題目
先寫出轉移方程
\(f[i]\)表示前\(i\)個已經裝箱完畢的最優解,\(s[i]\)表示前\(i\)項\(c[i]+1\)的和,
\[f[i]=f[j]+(s[i]-s[j]+l+1)^2(j≤i)
\]用\(l+1\)代替\(l\)比較好處理,於是方程變成
\[f[i]=f[j]+(s[i]-s[j]+l)^2(j≤i)
\]我們要把式子變化成\(kx+b\)的形式,
要注意:移項要遵循的原則是:把含有 \(function(i) \ast function(j)\) 的表示式看作斜率 $k $乘以未知數 \(x\),含有 \(f[i]\) 的項必須要在\(b\)的表示式中,含有\(function(j)\) 的項必須在\(y\)的表示式中。如果未知數\(x\) 的表示式單調遞減,最好讓等式兩邊同乘個\(−1\),使其變為單增。
\[f[i]=f[j]+(s[i]-s[j]+l)^2(j≤i)
\]\[f[i]=f[j]+(s[i])^2+2 \ast s[i]\ast s[j] -2 \ast s[i]\ast l +(s[j]+l)^2
\]\[(2\ast s[i])\ast s[j]+f[i]-(s[i])^2+2 \ast s[i] \ast l=f[j]+(s[j]+l)^2
\]這裡的\(k=(2\ast s[i])\),\(x=s[j]\) ,\(b=s[j]+f[i]-(s[i])^2+2 \ast s[i] \ast l\),\(y=f[j]+(s[j]+l)^2\)
考慮到我們目標直線的\(k=2 \ast s[i]\)是不斷遞增的,凸包上的斜率也是不斷遞增的,就想到用單調佇列來維護。
要注意乙個細節,初始的時候\(q\)要給\(0\),不能給\(s[1]\),否則就認為\(1\)號必須單獨裝了
#includeusing namespace std;
typedef long long ll;
const int maxn=50005;
inline int read()
while(ch<='9'&&ch>='0')ret=ret*10+ch-'0',ch=getchar();
return ret*f;
}ll n,l,hed=1,til,q[maxn],s[maxn],dp[maxn];
inline ll x(ll j)
inline ll y(ll j)
inline long double calc(ll i,ll j)
int main()
printf("%lld\n",dp[n]);
return 0;
}
P3195 HNOI2008 玩具裝箱TOY
題目描述 p教授要去看奧運,但是他捨不下他的玩具,於是他決定把所有的玩具運到北京。他使用自己的壓縮器進行壓縮,其可以將任意物品變成一堆,再放到一種特殊的一維容器中。p教授有編號為1 n的n件玩具,第i件玩具經過壓縮後變成一維長度為ci.為了方便整理,p教授要求在乙個一維容器中的玩具編號是連續的。同時...
P3195 HNOI2008 玩具裝箱TOY
紀念不看題解 a 掉的第乙個斜率優化dp p3195 hnoi2008 玩具裝箱toy 乙個月後補的重點 斜率優化的本質就是利用推出來的公式決定維護乙個凸包,用單調佇列來維護這個凸包,因為我們假定 jdp k 所以每次決策顯然就取隊頭,從而得到最優解 定義陣列 sum i 為長度字首和,陣列 dp ...
洛谷P3195 HNOI2008 玩具裝箱TOY
題目 p教授要去看奧運,但是他捨不下他的玩具,於是他決定把所有的玩具運到北京。他使用自己的壓縮器進行壓縮,其可以將任意物品變成一堆,再放到一種特殊的一維容器中。p教授有編號為1.n的n件玩具,第i件玩具經過壓縮後變成一維長度為ci.為了方便整理,p教授要求在乙個一維容器中的玩具編號是連續的。同時如果...