1. 程式人生 > >5-12 修理牧場 (25分)——最小堆->哈夫曼樹+快速排序

5-12 修理牧場 (25分)——最小堆->哈夫曼樹+快速排序

think:
1通過最小堆生成哈夫曼樹+快速排序

5-12 修理牧場 (25分)

農夫要修理牧場的一段柵欄,他測量了柵欄,發現需要NNN塊木頭,每塊木頭長度為整數LiL_iL​i​​個長度單位,於是他購買了一條很長的、能鋸成NNN塊的木頭,即該木頭的長度是LiL_iL​i​​的總和。
但是農夫自己沒有鋸子,請人鋸木的酬金跟這段木頭的長度成正比。為簡單起見,不妨就設酬金等於所鋸木頭的長度。例如,要將長度為20的木頭鋸成長度為8、7和5的三段,第一次鋸木頭花費20,將木頭鋸成12和8;第二次鋸木頭花費12,將長度為12的木頭鋸成7和5,總花費為32。如果第一次將木頭鋸成15和5,則第二次鋸木頭花費15,總花費為35(大於32)。
請編寫程式幫助農夫計算將木頭鋸成NNN塊的最少花費。

輸入格式:
輸入首先給出正整數NNN(≤104\le 10^4≤10​4​​),表示要將木頭鋸成NNN塊。第二行給出NNN個正整數(≤50\le 50≤50),表示每段木塊的長度。

輸出格式:
輸出一個整數,即將木頭鋸成NNN塊的最少花費。

輸入樣例:
8
4 5 1 2 1 3 1 1

輸出樣例:

49

Hint:

測試點1    答案正確    12/12   1   1   sample
測試點2    答案正確    1/1     2   1   只有一段木頭,不用鋸
測試點3    答案正確    6/6     5   1   最大N,最長木段,輸出的最大值
測試點4    答案正確    6
/6 6 1 最大N隨機資料

以下為答案正確程式碼

#include <stdio.h>
#include <stdlib.h>
#define MINDATA -1
typedef struct node
{
    int *Data;
    int Size;
}MinHeap;
MinHeap * Creat(int MaxSize)
{
    MinHeap *H = (MinHeap *)malloc(sizeof(MinHeap));
    H->Data = (int *)malloc((MaxSize + 1)*sizeof
(int)); H->Size = 0; H->Data[0] = MINDATA; return H; } void Insert(MinHeap *H, int x) { int i = ++H->Size; for(; H->Data[i/2] >= x; i /= 2) H->Data[i] = H->Data[i/2]; H->Data[i] = x; } int Delete(MinHeap *H) { int MinItem, X, parent, child; MinItem = H->Data[1]; X = H->Data[H->Size--]; for(parent = 1; parent*2 <= H->Size; parent = child) { child = parent*2; if((child != H->Size) && H->Data[child] > H->Data[child+1]) child++; if(X <= H->Data[child]) break; else H->Data[parent] = H->Data[child]; } H->Data[parent] = X; return MinItem; } void PercDown(MinHeap *H, int p) { int X, parent, child; X = H->Data[p]; for(parent = p; parent*2 <= H->Size; parent = child) { child = parent*2; if((child != H->Size) && H->Data[child] > H->Data[child+1]) child++; if(X <= H->Data[child]) break; } H->Data[parent] = X; } void GetBuild(MinHeap *H) { for(int i = H->Size/2; i > 0; i--) { PercDown(H, i); } } int cmp(const void *a, const void *b) { return ((*(int *)a) - (*(int *)b)); } int main() { int n, i, x1, x2, sum, y, ans[14000]; MinHeap *H1; while(scanf("%d", &n) != EOF) { sum = 0; H1 = Creat(n); H1->Size = n; for(i = 1; i <= n; i++) { scanf("%d", &ans[i]); } qsort(&ans[1], n, sizeof(ans[1]), cmp); for(i = 1; i <= n; i++) { H1->Data[i] = ans[i]; } GetBuild(H1); for(i = 0; i < n-1; i++) { x1 = Delete(H1); x2 = Delete(H1); y = x1 + x2; sum += y; Insert(H1, y); } printf("%d\n", sum); } }