Fence Repair(poj 3253)

题意:

有一个农夫要把一个木板钜成几块给定长度的小木板,每次锯都要收取一定费用,这个费用就是当前锯的这个木版的长度

给定各个要求的小木板的长度,及小木板的个数n,求最小费用

提示:

3

5 8 5为例:

先从无限长的木板上锯下长度为 21 的木板,花费 21

再从长度为21的木板上锯下长度为5的木板,花费5

再从长度为16的木板上锯下长度为8的木板,花费8

总花费 = 21+5+8 =34

思路:典型的哈夫曼树问题,但因为数据量较大,应该用优先队列优化

#include<cstdio>
#include<iostream>
#include<queue>
#define LL long long
using namespace std;
int main()
{
    int n;
    while(scanf("%d",&n)==1)
    {
        priority_queue<int,vector<int>,greater<int> > q;
        for(int i=1;i<=n;i++)
        {
            int x;
            scanf("%d",&x);
            q.push(x);
        }
        LL sum=0;
        if(q.size()==1)
        {
            int a=q.top();
            sum+=a;
            q.pop();
        }
        while(q.size()>1)
        {
            int t=0;
            int a=q.top();
            t+=a;
            q.pop();
            int b=q.top();
            t+=b;
            q.pop();
            sum+=t;
            q.push(t);
        }
        printf("%lld",sum);
    }
} 
View Code
原文地址:https://www.cnblogs.com/harden/p/5623825.html