题意:FJ要修栅栏,要用n段木板,每段长Li,现在FJ有一块长为∑Li的木板,要把这块木板分成n段,需要切割n-1次,每次的费用是当前木板长度,问最少要用多少费用。
解法:利用哈弗曼树的思想贪心,用优先队列维护。每次取最小的两个木板,再将和放到优先队列中。
代码:
#include<stdio.h> #include<iostream> #include<algorithm> #include<string> #include<string.h> #include<math.h> #include<limits.h> #include<time.h> #include<stdlib.h> #include<map> #include<queue> #include<set> #include<stack> #include<vector> #define LL long long using namespace std; struct node { LL a; bool operator < (const node &tmp) const { return a > tmp.a; } }; priority_queue <node> q; int main() { int n; while(~scanf("%d", &n)) { while(!q.empty()) q.pop(); LL x; for(int i = 0; i < n; i++) { scanf("%lld", &x); q.push((node){x}); } LL ans = 0; while(q.size() > 1) { LL tmp = q.top().a; q.pop(); tmp += q.top().a; q.pop(); q.push((node){tmp}); ans += tmp; } printf("%lld ", ans); } return 0; }