Time Limit: 2000MS Memory Limit: 65536K
Total Submissions: 7947 Accepted: 2530

     本题其实很简单,就是简单的赫夫曼,因为每次将他们分开两半的时候都要按照长度收费,也就是说第一次被分开的只收费了一次,第二次被分开的收费了二次(因为前面已经收费了一次)......第n次分开的要收费n次。就是求如何合理的安排是的总费用最小,这是典型的最优生成树的问题,根据所给的数据作为权值生成赫夫曼树,然后再计算一下总的权值即可。

注意:本题的记过可能很大,用Int型估计不能过,建议__int64

代码:

 

1 #include<stdio.h>
2 #include<queue>
3  using namespace std;
4
5 typedef struct T
6 {
7 int data;
8 struct T *Lchild,*Rchild;
9 }*Tree;
10 typedef struct node
11 {
12 int data;
13 int h;
14 Tree t;
15 bool operator <(const node &a) const
16 {
17 if(a.data!=data)
18 return a.data<data;
19 else
20 return a.h<h;
21 }
22 }NODE;
23 NODE cur,cur1,cur2;__int64 sum;
24 priority_queue<NODE> qu;
25  void createtree()
26 {
27 cur1=qu.top();
28 qu.pop();
29 if(qu.empty ())
30 return ;
31 cur2=qu.top();
32 qu.pop();
33 cur.data=cur1.data+cur2.data;
34 cur.h=1;
35 cur.t=(Tree)malloc(sizeof(T));
36 cur.t->Lchild=cur1.t;
37 cur.t->Rchild=cur2.t;
38 cur.t->data=0;
39 qu.push(cur);
40 createtree();
41 }
42 void visit(Tree root,int floor)
43 {
44 if(root->data!=0)
45 sum+=root->data*floor;
46 if(root->Lchild!=NULL)
47 visit(root->Lchild,floor+1);
48 if(root->Rchild !=NULL)
49 visit(root->Rchild,floor+1);
50 }
51 int main()
52 {
53 int n,a;
54 scanf("%d",&n);
55 sum=0;
56 while(n--)
57 {
58 scanf("%d",&a);
59 cur.data=a;
60 cur.h=0;
61 cur.t=(Tree)malloc(sizeof(T));
62 cur.t->data=a;
63 cur.t->Lchild =NULL;
64 cur.t->Rchild =NULL;
65 qu.push(cur);
66 }
67 if(qu.size()==1)
68 {
69 printf("0\n");
70 }
71 else
72 {
73 createtree();
74 visit(cur1.t,0);
75 printf("%I64d\n",sum);
76 }
77 return 0;
78 }
79
80