P1334 瑞瑞的木板
阿新 • • 發佈:2018-08-03
表示 根據 esp 一切都 圖片 sin ace 繼續 pen
題目描述
瑞瑞想要親自修復在他的一個小牧場周圍的圍欄。他測量柵欄並發現他需要N(1≤N≤20,000)根木板,每根的長度為整數Li(1≤Li≤50,000)。
於是,他神奇地買了一根足夠長的木板,長度為所需的N根木板的長度的總和,他決定將這根木板切成所需的N根木板。
(瑞瑞在切割木板時不會產生木屑,不需考慮切割時損耗的長度)瑞瑞切割木板時使用的是一種特殊的方式,
這種方式在將一根長度為x的模板切為兩根時,需要消耗x個單位的能量。
瑞瑞擁有無盡的能量,但現在提倡節約能量,所以作為榜樣,他決定盡可能節約能量。
顯然,總共需要切割N-1次,問題是,每次應該怎麽切呢?請編程計算最少需要消耗的能量總和。
輸入輸出格式
輸入格式:
第一行: 整數N,表示所需木板的數量
第2到N+1行: 每行為一個整數,表示一塊木板的長度
輸出格式:
一個整數,表示最少需要消耗的能量總和
輸入輸出樣例
輸入樣例#1: 復制3
8
5
8
輸出樣例#1: 復制
34
說明
將長度為21的木板,第一次切割為長度為8和長度為13的,消耗21個單位的能量,
第二次將長度為13的木板切割為長度為5和8的,消耗13個單位的能量,共消耗34個單位的能量,是消耗能量最小的方案。
感覺跟合並果子挺像的吧。
然後就很自然的想到了一種思路,,
一開始答案就等於所有元素的和(肯定的),
在此基礎上用貪心的方法繼續加。
看著根據樣例好像也對,,
就交上了,,,
十分mmp。。
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<queue> 7 using namespace std; 8 9 priority_queue<int10分lj,vector<int>,greater<int> > q; 10 int n; 11 int a[20002]; 12 long long ans,b; 13 14 int main() 15 { 16 scanf("%d",&n); 17 for(int i=1;i<=n;++i) 18 { 19 scanf("%d",&a[i]); 20 ans+=a[i]; 21 q.push(a[i]); 22 } 23 while(q.size() !=1) 24 { 25 b=q.top() ; 26 q.pop() ; 27 b+=q.top() ; 28 q.pop() ; 29 ans+=b; 30 } 31 printf("%lld",ans); 32 return 0; 33 }
然後可以換一種思路,,
雖然並不怎麽清楚原來的思路的問題。
多舉幾個樣例就能知道了。
所以ans一開始不必等於所有元素和,
跟上面思路也差不多,
就是可以在踢走最小的元素之後,
把兩個最小的元素和在放入堆中。
就可以了。
代碼:
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<algorithm> 5 #include<cstring> 6 #include<queue> 7 using namespace std; 8 9 priority_queue<int,vector<int>,greater<int> > q; 10 int n; 11 int a[20002]; 12 long long ans,b; 13 14 int main() 15 { 16 scanf("%d",&n); 17 for(int i=1;i<=n;++i) 18 { 19 scanf("%d",&a[i]); 20 q.push(a[i]); 21 } 22 for(int i=1;i<=n-1;++i) 23 { 24 b=q.top() ; 25 q.pop() ; 26 b+=q.top() ; 27 q.pop() ; 28 ans+=b; 29 q.push(b); 30 } 31 printf("%lld",ans); 32 return 0; 33 }
如果你不開心,那我就把右邊這個帥傻子分享給你吧,
你看,他這麽好看,跟個zz一樣看著你,你還傷心嗎?
真的!這照片盯上他五秒鐘就想笑了。
一切都會過去的。
時間時間會給你答案2333
P1334 瑞瑞的木板