作业上的一道哈夫曼树的入门题。
题意大概是在一段无限长的木板上截下n段与要求相同的木板。每次切割需要花费切割长度的代价。让你求最小的代价是多少。
很容易想到这种贪心策略:每次割下最长的长度,这样可以使长的尽量少割。
但很容易发现这是行不通的,因为有些时候截下来的是几段的和而不是一段。
因此我们反向思考,既然不能一次截出最长的,那就从最小的开始分析,把最短的留到最后截。
因为满足次数关系,因此可以发现这就是哈夫曼树的板子。
用STL的优先队列即可,注意ans要开long long(50000^2超int了)
CODE
#include<cstdio> #include<queue> using namespace std; priority_queue < int,vector<int>,greater<int> > tree; int n,x,i; long long ans; inline void read(int &x) { x=0; char ch=getchar(); while (ch<'0'||ch>'9') ch=getchar(); while (ch>='0'&&ch<='9') x=x*10+ch-'0',ch=getchar(); } int main() { read(n); for (i=1;i<=n;++i) read(x),tree.push(x); for (i=1;i<n;++i) { int x=tree.top(); tree.pop(); int y=tree.top(); tree.pop(); ans+=x+y; tree.push(x+y); } printf("%lld",ans); return 0;