question
\(\text\)
首先有乙個基礎\(dp:\)設\(dp_i\)表示前\(i\)個物品裝完的最小價值,\(sum[i]\)是\(c\)的字首和則:
\(dp_i=\min_\),對應到本題當中即可。
更新佇列的時候,如果當前隊頭的斜率小於當前\(i\)對應直線的斜率,則捨棄;找到的第乙個就是我們要找的點。
加入\(i\)的時候,判斷隊尾是不是能夠被刪掉,一種常用的寫法是\(slope(q[tail-1],q[tail])>=slope(q[tail],i)\)的時候,出隊。因為它前面的點的斜率是要小於這個點與上乙個點所連直線的斜率的。
以上,這題時間複雜度\(o(n).\)
再多說一句:至於為何要用直線斜率為\(2sum[i]\)的直線去掃,是因為當斜率確定,則直線的形狀確定,唯一不知道的是截距。我們要最小化截距,還要由乙個決策點轉移而來,故我們可以從下往上平移這個直線,觸碰到的第乙個點必然是凸包上的下凸點,碰到第乙個點必然最靠下,同理其截距也就最小。因為知道斜率\(k\),我們只需要再知道乙個點,就可以唯一確定這一條直線了。於是,我們要找的點就是我們單調佇列中所維護的第乙個斜率大於當前斜率的點。
#includeusing namespace std;
#define int long long
int n,l,dp[500010];
int sum[500010];
int q[500010],tail,head;
int sq(int x)
inline int y(int x)
inline int x(int x)
double slope(int x,int y)
signed main()
cout
}
P3195 HNOI2008 玩具裝箱 題解
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...
luogu P3195 玩具裝箱 斜率優化題解
題意簡述 現有n 個物品,第 i個物品的長度為ci 可以製造若干個容器,容器的數量和長度不限制,但是只能把連續若干個物品放入容器中。把物品區間 i,j 放入同乙個容器中,長度為 每乙個容器的製造代價為,l 為給定常數。求最小代價之和。資料範圍 對於100 的資料,原題鏈結 如果只要部分分,那麼容易設...
斜率優化DP 玩具裝箱
hnoi2008 玩具裝箱toy time limit 1000ms memory limit 165536k total submit 5 accepted 5 description p教授要去看奧運,但是他捨不下他的玩具,於是他決定把所有的玩具運到北京。他使用自己的壓縮器進行壓縮,其可以將任意...