【算法基础26】贪心下——哈夫曼树、排序不等式、绝对值不等式、推公式的思路与应用
一、合并果子(哈夫曼树)
题目描述:给出n堆不同种类的果子,每堆果子的数量不同,每个果子的重量为1。每次只能合并相邻堆的果子,且花费的体力是果子的重量和。将所有果子合并成一堆,求最小的体力花费。
问题分析:每次选出重量最小的两堆进行合并,并将合并后的堆的重量加入,最终从下往上地构成了一颗哈夫曼树,树的根为合并所有果子的最小体力花费。
具体解法:
#include<iostream>
#include<queue>
using namespace std;int main(){int n;cin>>n;priority_queue<int,vector<int>,greater<int>> heap;//小根堆while(n--){int x;cin>>x;heap.push(x);}int res=0;while(heap.size()>1){int a=heap.top();heap.pop();//找出最小的两个元素int b=heap.top();heap.pop();res+=a+b;heap.push(a+b);//将合并后的数加入小根堆}cout<<res;//注意heap.top()只是最后一次合并的开销,不是总开销return 0;
}
输出示例:
二、排队打水(排序不等式)
题目描述:有n个人排队打水,每个人接水的时间是 ti ,怎样安排才能使总共等待时间最小?输出最小等待时间。
题目分析:设第一个人打水的时间为t1,可知总时间T=t1*(n-1)+t2*(n-2)....+tn,则可以按照打水时间从小到大进行排队,总时间最短。
具体解法:
#include<iostream>
#include<algorithm>
using namespace std;const int N=1010;
int t[N];int main(){int n;cin>>n;for(int i=0;i<n;i++) cin>>t[i];sort(t,t+n);long long res=0;//防止结果溢出for(int i=0;i<n;i++) res+=t[i]*(n-i-1);cout<<res;return 0;
}
输出示例:
三、货仓选址(绝对值不等式)
题目描述:在数轴上有N家商店位于A1、A2...An,建立一家货仓使得每家商店到货仓的距离之和最小,求最小距离为多少。
问题分析:将函数项首尾分组,可以将求所有商店到货仓的距离转化为n/2个两商店到货仓距离的子问题。又由 |a-x| + |b-x| <= b-a 可以将函数进行放缩,当 x 取为n个数的中位数时可以使等号成立,此时该距离为最短距离。
具体解法:
#include<iostream>
#include<algorithm>
using namespace std;const int N=1010;
int a[N];int main(){int n;cin>>n;for(int i=0;i<n;i++) cin>>a[i];sort(a,a+n);int res=0;for(int i=0;i<n;i++) res+=abs(a[i]-a[n/2]);cout<<res;return 0;
}
输出示例:
四、耍杂技的牛(推公式)
题目描述:n只牛叠罗汉,每只牛的重量为w,强壮值为s,危险系数为上面所有牛的重量减去它自身的强壮系数。求危险系数的最大值最小为多少。
问题分析:重量排序类比排队打水问题,重量小的放在前面累加的次数少,而强壮值越大所能承受的重量越大,越应该排在后。综合之后按照w+s排序。
具体解法:
#include<iostream>
#include<algorithm>
using namespace std;const int N=1010;
typedef pair<int,int> PII;
PII cow[N];int main(){int n;cin>>n;for(int i=0;i<n;i++){int w,s;cin>>w>>s;cow[i]={w+s,w};//要按w+s排序,可以直接把第一个数存成w+s}sort(cow,cow+n);int res=-2e9,sum=0;for(int i=0;i<n;i++){int w=cow[i].second,s=cow[i].first-w;//由和以及一个已知数能求另一个未知数res=max(res,sum-s);sum+=w;}cout<<res;return 0;
}
输出示例:
参考资料:acwing算法基础
【算法基础26】贪心下——哈夫曼树、排序不等式、绝对值不等式、推公式的思路与应用相关推荐
- 算法漫画:什么是 “哈夫曼树” ?
----- 第二天 ----- ------------ 概念1:什么是路径? 在一棵树中,从一个结点到另一个结点所经过的所有结点,被我们称为两个结点之间的路径. 上面的二叉树当中,从根结点A到叶 ...
- 1道动态规划(搬箱子)、KMP算法、图(Prim算法)、1道哈夫曼树
1.最长递增子序列 华华要给厂里进一批新箱子共n个(n<=500),编号为1到n,用一个正整数ai(1<=ai<=10000)(1<=i<=n)来表示编号为i的箱子的高度 ...
- 算法学习笔记10——应用哈夫曼树构造最短的不等长编码方案
内容: (1)设需要编码的字符集为{d1, d2, -, dn},它们出现的频率为{w1, w2, -, wn},应用哈夫曼树构造最短的不等长编码方案. 提示: 哈夫曼树(Huffman Tree), ...
- 算法学习笔记——数据结构:哈夫曼树、带权路径长度WPL、哈夫曼编码
引入 合并果子问题如下: 有n堆果子,每次可以合并任意两堆果子,耗费体力值为[两堆果子数之和],最终在n-1次合并后,得到一堆果子. 给出合并的方案,使得耗费的体力值最小 例如有3堆果子,质量依次为1 ...
- 本科课程【数据结构与算法】实验4—— 构造哈夫曼树、深度优先搜索
大家好,我是[1+1=王], 热爱java的计算机(人工智能)渣硕研究生在读. 如果你也对java.人工智能等技术感兴趣,欢迎关注,抱团交流进大厂!!! Good better best, never ...
- 【51Nod - 1117 】聪明的木匠 (贪心,哈夫曼树,时光倒流)
题干: 一位老木匠需要将一根长的木棒切成N段.每段的长度分别为L1,L2,......,LN(1 <= L1,L2,-,LN <= 1000,且均为整数)个长度单位.我们认为切割时仅在整数 ...
- 赫夫曼树赫夫曼编码的创建
目录 基础知识点 最优二叉树 如何构造赫夫曼树 赫夫曼编码 编码与压缩文件 代码 结构体设计 创建赫夫曼树 创建构建赫夫曼编码 基础知识点 赫夫曼树又称为最优树,是一种带权路径长短最短的树,有着广泛的 ...
- 哈夫曼树(最优二叉树)(c/c++)
哈夫曼编码 halfman! halfman! 半人万岁!(来自权力的游戏 Tyrion Lannister) huffman coding哈夫曼编码的核心是构造哈夫曼树─即最优二叉树,带权路径长度最 ...
- Python实现霍夫曼树
Python实现霍夫曼树 霍夫曼树是一种特殊的二叉树,是一种带权路径长度最短的二叉树,又称为最优二叉树. 给定 N 个权值作为二叉树的 N 个叶节点的权值,构造一棵二叉树,若该二叉树的带权路径长度达到 ...
最新文章
- 《开源者说》08期:聊聊Java那些事儿
- USB开发基础:USB设备的开发流程
- golang []byte和string相互转换
- 最优布线问题(普里姆算法)
- Kafka是什么,JMS是什么,常见的类JMS消息服务器,为什么需要消息队列(来自学习笔记)
- 测试之道--阿里巴巴八年测试专家倾情奉献
- mysql not exists很慢_查询速度优化用not EXISTS 代替 not in
- Launcher3桌面Icon的文字size的 修改
- C#中DataGradView控件的常用操作
- java 性能测试文档模板_最好用的数据库文档生成工具
- Mysql触发器学习
- Fiddler 5.0 中文版
- 裴礼文数学分析中的典型问题与方法第3章一元微分学练习
- 暴力法——猴子分桃-源代码 c语言实现
- Ubuntu12.04解决集成HD3000显卡安装后系统详情显示图形 驱动 未知的方法
- Python:PDF文件处理(数据处理)
- 经典编程书籍大全-python
- Java中双冒号(::)运算操作符
- 生物技术如何利用计算机思维,阿米巴,真正强大的生物计算机了解一下?
- Android Vitamio的使用解析
热门文章
- P4924 [1007]魔法少女小Scarlet
- 第十四届蓝桥杯(Web 应用开发)模拟赛 1 期-职业院校组-知识点题解
- @Async 异步任务自定义线程池的配置方法和 @Scheduled 定时任务自定义线程池的配置方式
- 对 matplotlib.cm.RdYlBu() 的理解
- Flutter | bloc 之 state 使用优化
- Day2 - Wanan 么么哒。
- Abrash和TimSweeney两个文章
- 谷粒商城-04-P44-P60
- 用邮件联系导师有哪些注意事项需要关注呢?如何选择适合自己的导师呢?
- 基于微信在线考试小程序系统设计与实现 开题报告