POJ 3253 Fence Repair(简单哈弗曼树_水过)

题目大意:原题链接

锯木板,锯木板的长度就是花费。比如你要锯成长度为8 5 8的木板,最简单的方式是把21的木板割成13,8,花费21,再把13割成5,8,花费13,共计34,当然也可以先割成16,5的木板,花费21,再把16割两个8,花费16,总计37,现在就是问你花费最少的情况。

思路:转化为哈弗曼树

解法一:AC

#include<cstdio>
#include<algorithm>
#define maxn 20010
using namespace std;
int n,a[maxn];
void get_min(int x)
{
    int p=x;
    for(int i=x+1;i<=n;i++){
        if(a[i]<a[p])
            p=i;
    }
    swap(a[p],a[x]);
}
int main()
{
    while(scanf("%d",&n)!=EOF){
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]); 
        long long ans=0;
        for(int i=1;i<n;i++){
            get_min(i);
            ans+=a[i];
            get_min(i+1);
            ans+=a[i+1];
            a[i+1]+=a[i];
        }
        printf("%lld",ans);
    }
}

解法二:优先队列AC

#include<cstdio>
#include<queue>
using namespace std;
int n,d;
priority_queue<int,vector<int>,greater<int> > que;
int main()
{
    while(scanf("%d",&n)!=EOF){
        while(!que.empty()) 
            que.pop();
        for(int i=1;i<=n;i++){
            scanf("%d",&d);
            que.push(d);
        }
        long long ans=0;
        while(que.size()!=1){
            int x=que.top();
            que.pop();
            int y=que.top();
            que.pop();
            ans+=(x+y);
            que.push(x+y);
        }
        printf("%lld\n",ans);
    }
}
posted @ 2017-02-20 19:31  despair_ghost  阅读(132)  评论(0编辑  收藏  举报