这一题很明显可以用哈夫曼树去解决,因为它其实就是建立哈夫曼树的过程,要求把木头锯成N块木块,而且要最少花费,其实在建立哈夫曼树的过程相当于把锯出来的木头按最少花费的方式结合回去。
#include<iostream>
#include<queue>
#include<algorithm>
using namespace std;
typedef struct Node{
int data;
int parent;
}Node;
void SelectSmall(Node *a,int &least,int &less,int n)
{
int cnt=0;
for(int i=0;i<n;i++)
{
if(a[i].parent==-1)
{
//先处理两个数作为最小和次小
if(cnt==0) least=i;
else if(cnt==1) {
if(a[i].data<a[least].data)
{
less=least;least=i;
}
else
less=i;
}
//若是其他的数,那么就直接对最小和次小进行比较,看是否需要更新
else
{
if(a[i].data<a[least].data)
{
less=least;least=i;
}
else
{
if(a[i].data<a[less].data)
less=i;
}
}
cnt++;
}
}
}
int Cost(Node *a,int n)
{
int cost=0;
for(int i=n;i<2*n-1;i++)
{
int least,less;
//SelectSmall的作用是从未结合的结点中选出最小和次小的结点
SelectSmall(a,least,less,i);
a[least].parent=i;a[less].parent=i;
a[i].data=a[least].data+a[less].data;
a[i].parent=-1;
//cout<<a[i].data<<endl;
}
for(int i=n;i<2*n-1;i++)
cost+=a[i].data;
return cost;
}
int main()
{
Node a[30005];
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>a[i].data;
a[i].parent=-1;
}
cout<<Cost(a,n)<<endl;
}