懒省事的小明

时间限制: 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
来源
[hzyqazasdf]原创
上传者

hzyqazasdf

标准的哈夫曼树,一直没搞懂是怎么算的,原来是这样:终于搞懂是怎么算的了。比如说4个数3 4 5 9.结果为40.怎么算呢。就是先取出最小的两个3 4.求和ans=3+4=7;然后把7放进所有的里面编程7 5 9.取出最小的两个 5 7。ans+=7+5+7=19;把这两个数的和12放进去变成12 9.然后把剩下两个取出来12 9.ans+=19+12+9=40. 这就是哈夫曼树、 这里直接用优先队列实现。

优先队列代码:

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <queue>using namespace std;struct mycomp
{bool operator()(const int &a,const int &b){return a>b;}
};int main()
{priority_queue<long long,vector<long long>,mycomp> pp;int T,n,x;scanf("%d",&T);while(T--){long long ans=0;scanf("%d",&n);for(int i=0; i<n; i++){scanf("%d",&x);pp.push(x);}if(n==1){printf("%d\n",x);}else{while(pp.size()>1){int a=pp.top();pp.pop();int b=pp.top();pp.pop();int x=a+b;ans+=x;//printf("%d %d\n",a,b);pp.push(x);}printf("%lld\n",ans);}while(!pp.empty())pp.pop();}return 0;
}

multiset多重集合容器实现

#include <stdio.h>
#include <algorithm>
#include <string.h>
#include <iostream>
#include <queue>
#include <set>using namespace std;int main()
{int T,n,x;scanf("%d",&T);while(T--){multiset<long long> v;long long ans=0;scanf("%d",&n);for(int i=0; i<n; i++){scanf("%d",&x);v.insert(x);}if(n==1)printf("%d\n",x);else{while(v.size()>1){multiset<long long>::iterator it=v.begin();int a=*(it);int b=*(++it);v.erase(v.begin());v.erase(v.begin());ans+=(a+b);v.insert(a+b);}printf("%lld\n",ans);}}return 0;
}

牛人暴力代码:时间24
#include<stdio.h>
#include<string.h>
int a[13000];
int b[13000];
int fronta,frontb,reara,rearb;
void qqqsort(int low,int high,int a[])
{int i,j,x;if(low>high)return;i=low;j=high;x=a[i];while(i!=j){while(i<j&&a[j]>x)j--;if(i<j){a[i]=a[j];i++;}while(i<j&&a[i]<x)i++;if(i<j){a[j]=a[i];j--;}}a[i]=x;qqqsort(low,j-1,a);qqqsort(i+1,high,a);
}
int get()
{if(fronta==reara)return b[frontb++];if(frontb==rearb)return a[fronta++];return a[fronta]<b[frontb]?a[fronta++]:b[frontb++];
}
int main()
{long long ans,t;int n,m,i;scanf("%d",&n);while(n--){scanf("%d",&m);memset(a,0,sizeof(a));memset(b,0,sizeof(b));for(i=0; i<m; i++)scanf("%d",&a[i]);qqqsort(0,m-1,a);fronta=frontb=rearb=ans=0;reara=m;for(i=0; i<m-1; i++){t=get()+get();ans+=t;b[rearb++]=t;}printf("%lld\n",ans);}return 0;
}

转载于:https://www.cnblogs.com/james1207/p/3306467.html

nyoj 55 懒省事的小明 优先队列 multiset 还有暴力相关推荐

  1. NYOJ 55 懒省事的小明(优先队列)

    懒省事的小明 题目来源:点击打开链接 题目信息:由题意可知,每次都让最小的进行合并,再把合并的值放回队列中,如此循环...力气才最小 该题运用到了优先队列,先设定优先级,优先级大的先出对.和 &quo ...

  2. nyoj 55 懒省事的小明

    懒省事的小明 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 小明很想吃果子,正好果园果子熟了.在果园里,小明已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆 ...

  3. 《STL》— NYOJ 55 懒省事的小明

    题目55 题目信息 运行结果 本题排行 讨论区 懒省事的小明 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 小明很想吃果子,正好果园果子熟了.在果园里,小明已经将所有的 ...

  4. nyoj 55 懒省事的小明 (优先队列||直接插入)

    //优先队列 #include <stdio.h>//老大们可以注意了 ,一定要用long long 啊啊啊 我错了半页 就是一直用的int #include <queue> ...

  5. nyoj 55懒省事的小明

    #include <cstdio> #include <queue>using namespace std;// 本题就是对STL优先队列+哈夫曼树的初步应用 long lon ...

  6. 南洋理工 55 懒省事的小明

    懒省事的小明 时间限制:3000 ms  |           内存限制:65535 KB 难度:3 描述 小明很想吃果子,正好果园果子熟了.在果园里,小明已经将所有的果子打了下来,而且按果子的不同 ...

  7. NYOJ55 懒省事的小明【multiset的用法】

    原题链接 这题很坑,要用long long #include <cstdio> #include <set> using namespace std;int main(){in ...

  8. nyoj55懒省事的小明

    这个题没啥特别的,思想特别简单,就是我们学数据结构的时候,那里面的哈夫曼树的思想,从一组数里面选两个最小的相加,将这两个数从这组数中删除,再将这两个数的和放进去,再从这组数中选两个最小的数以此类推, ...

  9. 懒省事的小明(优先队列)

    懒省事的小明 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 小明很想吃果子,正好果园果子熟了.在果园里,小明已经将所有的果子打了下来,而且按果子的不同种类分成了不同的堆 ...

最新文章

  1. 【Linux系列】【基础版】第二章 文件、目录管理
  2. extjs6 mvvm_ZK 6中的MVVM初探
  3. 软件发布版本命名规则
  4. win32 destroywindow函数
  5. php手册中点击下载的功能,PHP实现文件下载功能
  6. 深入理解ob_flush和flush的区别(转)
  7. Map And Reduce Join的使用案例
  8. kubenerte启动_老司机和你深聊Kubenertes 资源分配之 Request 和 Limit 解析
  9. AndroidStudio编译引入JsonObject
  10. HeadFirstJava——3_变量
  11. element-ui 下拉框样式修改
  12. Scrapy项目 - 数据简析 - 实现豆瓣 Top250 电影信息爬取的爬虫设计
  13. 2018年sfdc工作总结_常见Salesforce 异常
  14. 前端优化中的防抖与截流
  15. MPB:农科院牧医所赵圣国组-微生物DNA、RNA和蛋白质共提取方法
  16. 用微信 远程遥控 服务器
  17. ROS安装:一键解决人生烦恼
  18. fabric cello
  19. 辰华宏命令(Macro Command)使用说明
  20. 2018年中国对美贸易顺差3233.2亿美元 同比扩大17.2%

热门文章

  1. c向文件中插入数据_Redis从文件中批量插入数据
  2. python人工智能_人工智能福利丨Python核心语法实战
  3. dataguard从库数据库丢失恢复例子(模拟所有的控制文件)
  4. Nginx配置proxy_pass
  5. Python全栈开发之3、数据类型set补充、深浅拷贝与函数
  6. C#中 Convert与Parse的区别
  7. 如何使用War包部署Tomcat
  8. go 二进制程序守护_图解 Go 程序是怎样跑起来的
  9. 专业本的C语言,以解决本专业问题为导向的C语言程序设计课程教学探索
  10. AUTOSAR从入门到精通100讲(九十八)-CANoe之Panel Designer的使用