BSOJ2684 鋸木廠選址(斜率優化)

2022-03-07 06:37:44 字數 1133 閱讀 1915

從山頂上到山底下沿著一條直線種植了n棵老樹。當地的**決定把他們砍下來。為了不浪費任何一棵木材,樹被砍倒後要運送到鋸木廠。木材只能按照乙個方向運輸:朝山下運。山腳下有乙個鋸木廠。另外兩個鋸木廠將新修建在山路上。你必須決定在**修建兩個鋸木廠,使得傳輸的費用總和最小。假定運輸每公斤木材每公尺需要一分錢。任務你的任務是寫乙個程式:從標準輸入讀入樹的個數和他們的重量與位置計算最小運輸費用將計算結果輸出到標準輸出(2≤n≤20 000)

設\(s[i]\)為重量字首和,\(sd[i]\)為距離字首和,\(d[i]\)為第\(i\)棵樹到第\(i+1\)棵樹的距離

那麼第乙個鋸木廠費用:\(cost[i]=cost[i-1]+s[i-1]*d[i-1]\)

而到第二個鋸木廠費用:\(w(i,j)=cost[j]-cost[i-1]-s[i-1]*(sd[j]-sd[i-1])\)

那麼\(ans=min\\)

亂搞一下發現斜率式,此時\(i>k>j\),且\(k\)比\(j\) 優

然後就完了

tips:

​ 由於\(s[k]>s[j]\)所以\(s[j]-s[k]<0\) 把斜率式變形的時候記得變符號

​ 因為不知道在哪設鋸木廠最優,用乙個\(ans\)變數隨時更新,否則wa

​ 雖然答案在int範圍,但是如果化除為乘的話中間結果要long long

#include #include #define n 20010

using namespace std;

int n,d[n],s[n],sd[n],cost[n],ans;

int l,r,q[n];

inline int read()

while(ch>='0'&&ch<='9')

return x*f;

}inline void init()

s[n+1]=s[n];

sd[n+1]=sd[n]+d[n];

cost[n+1]=cost[n]+d[n]*s[n];

}inline int f(int j,int k)

inline int g(int j,int k)

int h(int i,int j)

inline void dp()

}int main()

鋸木廠選址

這是我斜率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,因為這道題,當確定了第二個鋸木廠,第乙個鋸木廠的選擇是有決策單調性,其實斜率優化就是用了處理決策單調性的問題決策選...

Two Sawmills 鋸木廠選址

斜率優化dp,應該說是第一道斜率優化dp了,推公式的時候各種坑,還是參照了hzq神牛的思路,細節方面稍有不同,為了思維方便,我先將給出的序列翻轉了,也就是把從山頂到山下的點順序邊成了從山下到山頂,編號從1開始,第乙個點即為海拔最低的伐木場,所以共有n 1個點,w i 表示第i個點的重量,dist i...