poj 3253(哈夫曼樹priority_queue實現)

Fence Repair
Time Limit: 2000MS   Memory Limit: 65536K
Total Submissions: 21011   Accepted: 6697

Description

Farmer John wants to repair a small length of the fence around the pasture. He measures the fence and finds that he needsN (1 ≤N ≤ 20,000) planks of wood, each having some integer lengthLi (1 ≤Li ≤ 50,000) units. He then purchases a single long board just long enough to saw into theN planks (i.e., whose length is the sum of the lengthsLi). 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 theN-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 theN 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 makeN-1 cuts

Sample Input

3
8
5
8

Sample Output

34

Hint

He wants to cut a board of length 21 into pieces of lengths 8, 5, and 8.
The original board measures 8+5+8=21. The first cut will cost 21, and should be used to cut the board into pieces measuring 13 and 8. The second cut will cost 13, and should be used to cut the 13 into 8 and 5. This would cost 21+13=34. If the 21 was cut into 16 and 5 instead, the second cut would cost 16 for a total of 37 (which is more than 34).

Source


哈夫曼算法的核心思想就是,按照預先設想的排序準則s,構建一棵二叉樹。使得在排序準則s中排在前面的儘可能在樹的底層,排在後面的元素儘可能在樹的高層

而且 所有初始結點都在葉結點上

由二叉樹的性質:當一棵樹是二叉樹時(每個結點或者沒有子結點,或者有2個子結點),葉結點數=內結點數+1

因此當結點爲n時,需要n-1次合併操作。


huffman樹可以用priority_queue實現。需要重載<操作符。主要操作是push, top, pop操作

提交記錄:

1.Wrong Answer。居然是因爲沒有用long long 。題目中說好的是20000*50000,不知道爲何會暴int。莫名奇妙。

2.AC

代碼如下:

/*Source Code
Problem: 3253		User: 775700879
Memory: 1112K		Time: 47MS
Language: G++		Result: Accepted*/

    Source Code

    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #include 
    #define oo 1000000
    #define MAXV 500 * 2
    using namespace std;
    struct myint {
        long long num;
    };
    bool operator < (const myint & a, const myint & b) {
        return a.num > b.num;
    }
    int n;
    int main() {
        scanf("%d", &n);
        priority_queue pq;
        long long i, l;
        for (i = 0; i < n; i++) {
            scanf("%lld", &l);
            pq.push((myint){l});
        }
        long long result = 0;
        myint a, b;
        for (i = 1; i < n; i++) {
            a = pq.top(); 
            pq.pop();
            b = pq.top();
            pq.pop();
            result += (a.num+b.num);
            pq.push((myint){a.num+b.num});
        }
        //a = pq.top();
        //result += a.num;
        if (n == 1) cout << 0 << endl;
        else cout << result << endl;
        return 0;
    }

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章