從山頂上到山底下沿著一條直線種植了 n 棵老樹。樹被砍倒後要運送到鋸木廠。木材只能朝山下運。山腳下有乙個鋸木廠。另外兩個鋸木廠將新修建在山路上。你必須決定在**修建這兩個鋸木廠,使得運輸的費用總和最小。每公斤木材每公尺需要一分錢。
設 \(s_i\) 表示前 \(i\) 棵樹的重量之和,\(d_i\) 表示從第 \(i\) 棵樹到山腳的距離,那麼 \(f_i = \min_j (tot - s_j d_j - (s_i - s_j) d_i)\),相當於我們列舉了較低的乙個鋸木廠的位置 \(i\),要對較高的乙個位置 \(j\) 取 \(\min\)。
對於 \(j\),\(x\) 比 \(y\) 優,當且僅當 \(\frac > d_i\)。
於是維護乙個斜率單調遞減的上凸包,斜率即 \(\frac \),顯然我們希望找到乙個 \(x\) 使得 \(x+1\) 不比 \(x\) 優,那麼這時 \(x \to x+1\) 的斜率應該要小於 \(d_i\)。
因此我們求出隊首兩個點的斜率,如果大於 \(d_i\) 就彈出,那麼隊首就是答案。
至於隊尾,由於每次壓入的時候,要考慮到斜率的單調遞減,因此如果最後一段的斜率小於即將新加入的一段的斜率,那麼就需要在隊尾進行刪除。
#include using namespace std;
#define int long long
const int n = 1000005;
int n,d[n],w[n],s[n],c[n],f[n],tot,q[n],head=1,tail=0,ans=1e18;
double slope(int x,int y)
int calc(int i,int j)
signed main()
cout<}
鋸木廠選址
這是我斜率dp第乙個沒有一遍ac的,原因是第一遍忘開long long了。這一題比較特殊,細心的同學一定發現了,遞推式不帶f。為了方便,設d陣列的字尾和為sd i sd i 1 d i 設k陣列的字首和為sk i sk i 1 k i k i 即是題目中的w i 設f i 為第二個鋸木廠選在i時的最...
COGS鋸木廠選址(斜率優化)
這道題,需要選兩個鋸木廠,標定了選的份數,以前做的題都是可以分成任意的分數 實際上,這道題n 2列舉鋸木廠的位置,o 1 計算,找出最大值。算是斜率優化,感覺不是特別好說是斜率優化dp,因為這道題,當確定了第二個鋸木廠,第乙個鋸木廠的選擇是有決策單調性,其實斜率優化就是用了處理決策單調性的問題決策選...
洛谷P4360 CEOI2004 鋸木廠選址
做兩遍dp,dp k i 表示前i個位置放k個鋸木廠的最小值 先把整個順序反過來,那麼0的位置就是山腳的鋸木廠 設sum i f i 是sum i w i 字首和,f2 i 是w i 的字首和 dp 1 i f i f k sum k 1 f2 i f2 k dp 0 k 展開成f2 k sum k...