生活随笔
收集整理的這篇文章主要介紹了
分香肠
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
分香腸
Problem Description
有一根長長的美味香腸,為了給集訓隊的小朋友補充能量,現在要把這根香腸分為K份,每一份對應的長度為L1,L2,…,Lk。
然而香腸很硬,老周在切香腸的時候需要耗費一定的體力,消耗的體力數值等于香腸被切割后的長度之和。
舉個"栗子":比如需要把香腸切成5; 8; 8三種長度時,老周先把香腸切成8和13,消耗體力8+13 = 21;再將13切割成5和8,消耗體力5 + 8 = 13,所以總的消耗體力數值等于21 + 13 = 34。
請你把老周計算一下,怎么樣切割香腸,才能保證消耗的體力最小。
Input
輸入第一行包含一個正整數n(1 <= n <= 20000)
輸入第二行包含n個正整數L1…Ln(1 <= Li <= 50000)
Output
輸出最小的消耗體力數值
Sample Input:
2
2 6
Sample Output:
8
分析:
不是簡單的前綴和,因為有東西重復使用了。
下面代碼是錯誤的
#include<iostream>
#include<algorithm> using namespace std
;typedef long long ll
;
ll n
,a
[20001],sum
[20001];
int main(){cin
>>n
;for(ll i
=0;i
<n
;i
++){cin
>>a
[i
];}sort(a
,a
+n
);sum
[0]=a
[0];for(ll i
=1;i
<n
;i
++){sum
[i
]=sum
[i
-1]+a
[i
];}cout
<<sum
[n
-1];return 0;
}
正確代碼
分析:需要取出a和b之后,把a和b的和放進去,再進行累加。
舉個例子
想要分成5,8,8三段。第一次切成8+13(消耗體力21),第二次把13分成5+8(消耗體力13),總消耗21+13=34點體力,這個過程中13(5+8)被用了兩次。
這個可以使用優先隊列來做,
AC代碼
#include<iostream>
#include<algorithm>
#include<queue>
using namespace std
;typedef long long ll
;
const int maxn
=2e4+10;
ll n
,num
;
priority_queue
<ll
,vector
<ll
>,greater
<ll
> > que
;
int main(){cin
>>n
;for(ll i
=0;i
<n
;i
++){cin
>>num
;que
.push(num
);}ll low
,up
,sum
=0;while(que
.size()>1){low
=que
.top();que
.pop();up
=que
.top();que
.pop();sum
+=low
+up
;que
.push(low
+up
);}cout
<<sum
;return 0;
}
總結
以上是生活随笔為你收集整理的分香肠的全部內容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。