日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 >

[题解]CEOI 2004 锯木厂选址

發布時間:2025/7/14 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [题解]CEOI 2004 锯木厂选址 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【題目描述】

從山頂上到山底下沿著一條直線種植了n棵老樹。當地的政府決定把他們砍下來。為了不浪費任何一棵木材,樹被砍倒后要運送到鋸木廠。木材只能按照一個方向運輸:朝山下運。山腳下有一個鋸木廠。另外兩個鋸木廠將新修建在山路上。你必須決定在哪里修建兩個鋸木廠,使得傳輸的費用總和最小。假定運輸每公斤木材每米需要一分錢。
任務
你的任務是寫一個程序:
從標準輸入讀入樹的個數和他們的重量與位置
計算最小運輸費用
將計算結果輸出到標準輸出
【輸入】
輸入的第一行為一個正整數n——樹的個數(2≤n≤20 000)。樹從山頂到山腳按照1,2……n標號。
接下來n行,每行有兩個正整數(用空格分開)。
第i+1行含有:wi——第i棵樹的重量(公斤為單位)和 di——第i棵樹和第i+1棵樹之間的距離,1≤wi ≤10 000,0≤di≤10 000。最后一個數dn,表示第n棵樹到山腳的鋸木廠的距離。
保證所有樹運到山腳的鋸木廠所需要的費用小于2000 000 000分。
【輸出】
輸出只有一行一個數:最小的運輸費用。
【樣例輸入】
9
1 2
2 1
3 3
1 1
3 2
1 6
2 1
1 2
1 1
【樣例輸出】
26

-----------------------------------------------------------我是分界線----------------------------------------------------------------------

【題解】

裸的單調隊列優化DP。今天zyy腦子壞掉了,一直腦抽啊腦抽,一直調不過調不過,然后發現是方程推錯了= =|| 。各種糾結之后,仔細一看是符號弄錯了!!! 看來功力還是不夠啊。。

選擇兩個鋸木廠,那么整條河流就被分成了三段,花費計算如下:

f[i]=w[1]*(x[j]-x[1])+w[2]*(x[j]-x[2])+...+w[j]*(x[j]-x[j]) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? //1~j

? ? ? +w[j+1]*(x[i]-x[j+1])+w[j+2]*(x[i]-x[j+2])+...+w[i]*(x[i]-x[i]) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?//j+1~i

? ? ? +w[i+1]*(x[n+1]-x[i+1])+w[i+2]*(x[n+1]-x[i+2])+...+w[n]*(x[n+1]-x[n]) ? ? ? ? ? ? //i+1~n

化簡之后:f[i]=Delta+Sum[w[j]]*x[j]-Sum[w[j]]*x[i] ?

我們令X=Sum[w[j]] ,Y=Sum[w[j]]*x[j] 。 當i固定時,維護(X,Y)。

下面給出代碼:

View Code 1 #include<iostream> 2 #include<cstdio> 3 using namespace std; 4 #define MAXN 20020 5 #define INF 0x7fffffff 6 int w[MAXN],d[MAXN],x[MAXN]; 7 int q[MAXN],Front,Back; 8 int n; 9 int ans,Sum,Delta; 10 inline void Get_int(int &Ret) 11 { 12 char ch; 13 bool flag=false; 14 for(;ch=getchar(),ch<'0'||ch>'9';) 15 if(ch=='-') 16 flag=true; 17 for(Ret=ch-'0';ch=getchar(),ch>='0'&&ch<='9';Ret=Ret*10+ch-'0'); 18 flag&&(Ret=-Ret); 19 } 20 void Read() 21 { 22 Get_int(n); 23 int i; 24 for(i=1;i<=n;i++) 25 { 26 Get_int(w[i]),Get_int(d[i]); 27 x[i+1]=x[i]+d[i]; 28 Sum+=x[i]*w[i]; 29 w[i]+=w[i-1]; 30 } 31 } 32 inline double Get(int i,int j) 33 { 34 return (double)(w[i]*x[i]-w[j]*x[j])/(double)(w[i]-w[j]); 35 } 36 void Work() 37 { 38 ans=INF; 39 Front=0,Back=-1; 40 int i; 41 for(i=1;i<=n;i++) 42 { 43 while(Front<Back&&Get(q[Back],q[Back-1])>=Get(i,q[Back])) 44 Back--; 45 q[++Back]=i; 46 while(Front<Back&&Get(q[Front],q[Front+1])<=x[i]) 47 Front++; 48 Delta=w[i]*x[i]+x[n+1]*(w[n]-w[i])-Sum; 49 ans=min(ans,Delta+w[q[Front]]*x[q[Front]]-x[i]*w[q[Front]]); 50 } 51 printf("%d\n",ans); 52 } 53 int main() 54 { 55 Read(); 56 Work(); 57 return 0; 58 }

?

至此,此題完美解決。

轉載于:https://www.cnblogs.com/CQBZOIer-zyy/archive/2013/03/18/2966739.html

總結

以上是生活随笔為你收集整理的[题解]CEOI 2004 锯木厂选址的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。