zoukankan      html  css  js  c++  java
  • 树-堆结构练习——合并果子之哈夫曼树

     

    树-堆结构练习——合并果子之哈夫曼树

    Time Limit: 1000MS Memory limit: 65536K

    题目描述

     在一个果园里,多多已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。多多决定把所有的果子合成一堆。
    每一次合并,多多可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。多多在合并果子时总共消耗的体力等于每次合并所消耗体力之和。
    因为还要花大力气把这些果子搬回家,所以多多在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使多多耗费的体力最少,并输出这个最小的体力耗费值。
    例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以多多总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
     

    输入

     第一行是一个整数n(1<=n<=10000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个ai(1<=ai<=20000)是第i个果子的数目。
     

    输出

     输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。输入数据保证这个值小于2^31。
     

    示例输入

    3
    1 2 9

    示例输出

    15

    通过的代码(c++):
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <cstdlib>
     4 #include <iostream>
     5 
     6 using namespace std;
     7 
     8 struct N
     9 {
    10     int data;
    11     N *l,*r;
    12 };
    13 
    14 struct N *creat()
    15 {
    16     N *p = (N *)malloc(sizeof(N));
    17     p->l = p->r = NULL;
    18     return p;
    19 }
    20 
    21 void insert(N *&root,int data)
    22 {
    23     if(root == NULL)
    24     {
    25         root = creat();
    26         root->data = data;
    27     }
    28     else if(data >= root->data)
    29     {
    30         insert(root->r,data);
    31     }
    32     else
    33     {
    34         insert(root->l,data);
    35     }
    36 }
    37 
    38 int check(N *&root)
    39 {
    40     if(root->l == NULL)
    41     {
    42         int t = root->data;
    43         root = root->r;
    44         return t;
    45     }
    46     else
    47         return check(root->l);
    48 }
    49 
    50 int main()
    51 {
    52     int n,t,i,sum = 0;
    53     cin>>n;
    54     N *root = NULL;
    55     for(i = 0 ;i < n; i++)
    56     {
    57         cin>>t;
    58         insert(root,t);
    59     }
    60 
    61     int a,b;
    62 
    63     for(i = 1;i < n; i++)
    64     {
    65         a = check(root);
    66         b = check(root);
    67         sum += a+b;
    68         insert(root,a+b);
    69     }
    70 
    71     cout<<sum<<endl;
    72 
    73     return 0;
    74 
    75 } 
    View Code

    有疑问的代码(c):

     1 #include<stdio.h>
     2 #include<stdlib.h>
     3 #include<string.h>
     4 struct vode
     5 {
     6     int date;
     7     int l,r,p;
     8 } f[30008];
     9 void hf(struct vode f[],int n)
    10 {
    11     int m=2*n-1;
    12     int i;
    13     for(i=1; i<=30000; i++)
    14     {
    15         f[i].l=f[i].r=f[i].p=-1;
    16     }
    17     int j;
    18     for(j=n+1; j<=m; j++)
    19     {
    20         int x1=20005,x2=20005;
    21         int p1=0,p2=0;
    22         for(i=1; i<=j-1; i++) //整个循环是为了找出最小的两个数
    23         {
    24             if(f[i].p==-1)//表明f[i]未被标记,可用
    25             {
    26                 if(f[i].date<x1)//比最小的还小,是最小的
    27                 {
    28                     x2=x1;
    29                     x1=f[i].date;
    30                     p2=p1;
    31                     p1=i;
    32                 }
    33                 else if(f[i].date>=x1&&f[i].date<x2) //比最小的大,比第二小的还小,是第二小的
    34                 {
    35                     x2=f[i].date;
    36                     p2=i;
    37                 }
    38             }
    39         }
    40         f[p1].p=j;
    41         f[p2].p=j;
    42         f[j].date=x1+x2;
    43         f[j].l=p1;
    44         f[j].r=p2;
    45         /*for(i=1;i<=j;i++)
    46         printf("%d ",f[i].date);
    47         printf("
    ");*/
    48     }
    49 }
    50 int main()
    51 {
    52     int n;
    53     //while(~scanf("%d",&n))
    54     scanf("%d",&n);
    55     int i,sum=0;
    56     for(i=1; i<=n; i++)
    57     {
    58         scanf("%d",&f[i].date);
    59     }
    60     hf(f,n);
    61     for(i=n+1; i<=2*n-1; i++)
    62         sum=sum+f[i].date;
    63     printf("%d",sum);
    64     return 0;
    65 }
    View Code
  • 相关阅读:
    HDOJ-1106
    二进制神题--一千个苹果问题
    HDOJ-2160
    HDOJ-2058
    HDOJ-2045
    HDOJ-2034
    HDOJ-2054
    HDOJ-2036
    F
    B
  • 原文地址:https://www.cnblogs.com/kuangdaoyizhimei/p/3235280.html
Copyright © 2011-2022 走看看