POJ 3253 Fence Repair

Fence Repair
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 18686   Accepted: 5948

Description

Farmer John wants to repair a small length of the fence around the pasture. He measures the fence and finds that he needs N (1 ≤ N ≤ 20,000) planks of wood, each having some integer length Li (1 ≤ Li ≤ 50,000) units. He then purchases a single long board just long enough to saw into the N planks (i.e., whose length is the sum of the lengths Li). FJ is ignoring the "kerf", the extra length lost to sawdust when a sawcut is made; you should ignore it, too.

FJ sadly realizes that he doesn't own a saw with which to cut the wood, so he mosies over to Farmer Don's Farm with this long board and politely asks if he may borrow a saw.

Farmer Don, a closet capitalist, doesn't lend FJ a saw but instead offers to charge Farmer John for each of the N-1 cuts in the plank. The charge to cut a piece of wood is exactly equal to its length. Cutting a plank of length 21 costs 21 cents.

Farmer Don then lets Farmer John decide the order and locations to cut the plank. Help Farmer John determine the minimum amount of money he can spend to create the N planks. FJ knows that he can cut the board in various different orders which will result in different charges since the resulting intermediate planks are of different lengths.

Input

Line 1: One integer N, the number of planks  Lines 2..N+1: Each line contains a single integer describing the length of a needed plank

Output

Line 1: One integer: the minimum amount of money he must spend to make N-1 cuts

Sample Input

3
8
5
8

Sample Output

34

经典的赫夫曼树问题,做了好几天,终于搞出来了
起初帮同学写数据结构作业时学到了赫夫曼树算法,可是当时理解不够,把赫夫曼树和赫夫曼编码搞混了,还以为不用建树也能求,就简单地把所有数据排了个序,然后直接求了个和,结果就是——果断WA
后来又看了几本书的介绍,才算弄清楚赫夫曼树的意义所在,一板一眼地建树,然后求节点的和,然后——果断TLE
这道题就搁下了,一个就是几天
周日集训啥也没听懂,就在网上学了下堆排序,发现这道题可以用堆排序来模拟赫夫曼树,效率很高
构建赫夫曼树的过程就是每次取当前所有节点中权值最小的两个,构成一个新节点,所以我们就维护一个小顶堆,每次取一个最小值,维护一次,再取一个最小值,维护一次,再插入两个值的和
在主函数中每次求和即可

 1 #include<iostream>
 2 
 3 using namespace std;
 4 
 5 int num;
 6 long h[20001];
 7 
 8 void HeapAdjust(int s)
 9 {
10     long long temp=h[s];
11     for(int i=2*s;i<=num;i*=2)
12     {
13         if(i<num&&h[i]>h[i+1])
14             ++i;
15         if(temp<=h[i])
16             break;
17         h[s]=h[i];
18         s=i;
19     }
20     h[s]=temp;
21 }
22 
23 void HeapInsert(long long x)
24 {
25     int s=++num;
26     long long temp=x;
27 
28     for(int i=s/2;i>=1;i/=2)
29     {
30         if(h[i]<temp)
31             break;
32         h[s]=h[i];
33         s=i;
34     }
35 
36     h[s]=temp;
37 }
38 
39 long long get()
40 {
41     long long p,q;
42     p=h[1];
43     h[1]=h[num];
44     --num;
45     HeapAdjust(1);
46     q=h[1];
47     h[1]=h[num];
48     --num;
49     HeapAdjust(1);
50     HeapInsert(p+q);
51     return p+q;
52 }
53 
54 int main()
55 {
56     int n;
57     long long ans=0;
58 
59     cin>>n;
60 
61     num=n;
62     for(int i=1;i<=n;i++)
63         cin>>h[i];
64 
65     for(int i=num/2;i>=1;i--)
66         HeapAdjust(i);
67 
68     for(int i=1;i<n;i++)
69         ans+=get();
70 
71     cout<<ans<<endl;
72 
73     return 0;
74 }
[C++]

 

posted @ 2013-05-27 16:56  ~~Snail~~  阅读(144)  评论(0编辑  收藏  举报