POJ 3253

  作业上的一道哈夫曼树的入门题。

  题意大概是在一段无限长的木板上截下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;

 

posted @ 2018-03-10 14:26  空気力学の詩  阅读(138)  评论(1编辑  收藏  举报