• NYOJ 55 懒省事的小明



     

    懒省事的小明

    时间限制:3000 ms  |  内存限制:65535 KB
    难度:3
     
    描述
          小明很想吃果子,正好果园果子熟了。在果园里,小明已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆。小明决定把所有的果子合成一堆。 因为小明比较懒,为了省力气,小明开始想点子了:
      每一次合并,小明可以把两堆果子合并到一起,消耗的体力等于两堆果子的重量之和。可以看出,所有的果子经过n-1次合并之后,就只剩下一堆了。小明在合并果子时总共消耗的体力等于每次合并所耗体力之和。
      因为还要花大力气把这些果子搬回家,所以小明在合并果子时要尽可能地节省体力。假定每个果子重量都为1,并且已知果子的种类数和每种果子的数目,你的任务是设计出合并的次序方案,使小明耗费的体力最少,并输出这个最小的体力耗费值。
      例如有3种果子,数目依次为1,2,9。可以先将1、2堆合并,新堆数目为3,耗费体力为3。接着,将新堆与原先的第三堆合并,又得到新的堆,数目为12,耗费体力为12。所以小明总共耗费体力=3+12=15。可以证明15为最小的体力耗费值。
     
    输入
    第一行输入整数N(0<N<=10)表示测试数据组数。接下来每组测试数据输入包括两行,第一行是一个整数n(1<=n<=12000),表示果子的种类数。第二行包含n个整数,用空格分隔,第i个整数ai(1<=ai<=20000)是第i种果子的数目。
    输出
    每组测试数据输出包括一行,这一行只包含一个整数,也就是最小的体力耗费值。
    样例输入
    1
    3 
    1 2 9
    样例输出
    15
    
    代码一:
     1 //利用赫夫曼编码的思想,每次挑选最轻的两堆合并
     2 #include<cstdio>
     3 #include<algorithm>
     4 using namespace std;
     5 
     6 int main()
     7 {
     8     int T,n,i,j;
     9     long long sum;
    10     int num[12001];
    11     scanf("%d",&T);
    12     while(T--)
    13     {
    14         sum=0;
    15         scanf("%d",&n);
    16         for(i=0;i<n;++i)
    17             scanf("%d",&num[i]);
    18         sort(num,num+n);
    19         for(i=0;i<n-1;++i)
    20         {
    21             num[i]+=num[i+1];
    22             sum+=num[i];
    23             for(j=i+2;j<n;++j)
    24             {
    25                 if(num[i]>num[j])
    26                     num[j-1]=num[j];
    27                 else
    28                 {
    29                     num[j-1]=num[i];
    30                     break;
    31                 }
    32             }
    33             if(j==n)  //说明num[i]是最重的 直接插到最后
    34                 num[j-1]=num[i];
    35         }
    36         printf("%lld\n",sum);
    37     }
    38     return 0;
    39 }

     代码二:-------优先队列

     1 #include <cstdio>
     2 #include <iostream>
     3 #include <queue>
     4 
     5 using namespace std;
     6 
     7 int main()
     8 {
     9     long long T, n, tmp, t1, t2;
    10     priority_queue<long long, vector<long long>, greater<long long> > q;
    11     scanf("%lld", &T);
    12     while(T--)
    13     {
    14         while(!q.empty())
    15             q.pop();
    16         scanf("%lld", &n);
    17         for(int i = 0; i < n; ++i)
    18         {
    19             scanf("%lld", &tmp);
    20             q.push(tmp);
    21         }
    22         long long ans = 0;
    23         while(!q.empty())
    24         {
    25             t1 = q.top();
    26             q.pop();
    27             if(!q.empty())
    28             {
    29                 t2 = q.top();
    30                 q.pop();
    31                 t1 += t2;
    32                 ans += t1;
    33                 q.push(t1);
    34             }
    35         }
    36         printf("%lld\n", ans);
    37     }
    38     return 0;
    39 }
    
    
    功不成,身已退
  • 相关阅读:
    保存ADO的记录集为XML文件
    [C++] Undefined reference to vtable
    Csdn博客的一个bug
    深入解析ATL(第二版ATL8.0)(1.111.13节)
    不同操作系统下记事本的换行符号
    dom4j学习总结(一)
    关于firefox的copy/paste的问题
    php URL编码解码函数
    php连接MySQL数据库的一些问题
    使用 jQuery progressBar 做文件上传的进度条指示
  • 原文地址:https://www.cnblogs.com/dongsheng/p/2637167.html
Copyright © 2020-2023  润新知