问题描述

假设将一根金条切成两半,是需要花费和金条长度相同的钱。比如,一根80cm的金条,切成两半,需要花80块钱。现在,一群人想分一整块金条,每个人分得的长度保存在一个数组中,例如[10,20,30]意思就是将一根60cm的金条,划分成10,20,30三段,请问,怎样切分最省钱?
例如:
先将金条切分成10和50,需要60块钱,然后,再将50切分成20和30,需要50块,总共需要110块钱。
又或者,先将金条切分成30和30,花60块钱,然后再将30切分成10和20,花30块钱,总共就是90块钱。
90<110,所以第二种划算。

思路分析

首先,观察题目,可以发现,每切一次,只能切出来一段最终结果,另一端肯定还有继续切割,这一段最终结果是不需要再次切分了,也就说明,后面切分时就不需要再算这一段的钱了,因此,这一段最终结果的数值越大,总的代价就越小。也就是说,我们先把大的切出来,越省钱,大的不会再次计算价钱了,越小的,我们最后切出来。
因此,从上面分析出来的结果可以看出,其实,本质就是,减少数值大的遍历次数,增加数值小的遍历次数,这样总体代价最低。
哈夫曼树
这样的贪心算法有一种数据结构能够轻松实现,那就是哈夫曼树,哈夫曼树的构建过程,就是先把最小的两个相连,然后组成一个新节点,然后放入总的集合中,再从中找出最小的两颗子树再次相连,再将结果放入集合中,最终集合中只剩下一棵树,这棵树就是哈夫曼树。这道题其实就是哈夫曼树的应用。
小根堆
此题用哈夫曼树解决,为什么会提到小根堆呢?因此,哈夫曼树的构建过程,每次需要将两个子树合成的结果再次放入集合中,然后,再从集合中取出两个最小值。这个过程,如果用常规数组的话,每次放入后,是不是还需要再次排序呀?这个再次排序的过程,是不是小根堆效率很好啊?只需要调整小根堆就行了,最多logn,如果是一般方法,是不是每次都需要重新排序,效率极低的。
最终解题思路
先将数组构建成小根堆,然后,从小根堆中弹出两个。把这两个加在总和money上,然后这两个数相加,相加后,再次入小根堆。然后再从中弹出两个最小值,重复上述操作,直到小根堆中只剩一个数,结束,计算money。

代码

小根堆代码

public class littleHeap {int[] arr;int index;//堆中的最后一个元素的索引public littleHeap(int[] a) {arr = new int[a.length * 2];index = 0;for (int i = 0; i < a.length; i++) {arr[++index]=a[i];insert(arr,index);}}//弹出堆顶,并调整小根堆public int getTop(){if(index<1){System.out.println("见底了");return 0;}else if(index==1){index--;return arr[1];}else {int temp=arr[1];arr[1]=arr[index];arr[index]=temp;index--;int left=2;int father=1;while (left<=index){int right=left+1;int min;if(right>index){min=left;}else {min=arr[left]<arr[right]?left:right;}if(arr[min]<arr[father]){temp=arr[min];arr[min]=arr[father];arr[father]=temp;father=min;left=father*2;}else {break;}}return arr[index+1];}}//插入一个数public void insert(int num){arr[++index]=num;insert(arr,index);if(index==arr.length-1){int[] newArr=new int[arr.length*2];for (int i = 1; i < arr.length; i++) {newArr[i]=arr[i];}arr=newArr;}}private void insert(int[] arr, int index) {int father=index/2;while(father>=1&&arr[father]>arr[index]){int temp=arr[father];arr[father]=arr[index];arr[index]=temp;index=father;father=index/2;}}}

本题代码

        int[] arr=new int[]{20,10,30};littleHeap heap=new littleHeap(arr);int money=0;//index表示堆中末尾索引while (heap.index>1){int min1=heap.getTop();int min2=heap.getTop();money+=min1+min2;heap.insert(min1+min2);}System.out.println("最小花费为:"+money);

切金条问题(贪心思想+哈夫曼树+小根堆使用)相关推荐

  1. 【算法基础26】贪心下——哈夫曼树、排序不等式、绝对值不等式、推公式的思路与应用

    一.合并果子(哈夫曼树) 题目描述:给出n堆不同种类的果子,每堆果子的数量不同,每个果子的重量为1.每次只能合并相邻堆的果子,且花费的体力是果子的重量和.将所有果子合并成一堆,求最小的体力花费. 问题 ...

  2. 【51Nod - 1117 】聪明的木匠 (贪心,哈夫曼树,时光倒流)

    题干: 一位老木匠需要将一根长的木棒切成N段.每段的长度分别为L1,L2,......,LN(1 <= L1,L2,-,LN <= 1000,且均为整数)个长度单位.我们认为切割时仅在整数 ...

  3. 两个队列+k叉哈夫曼树 HDU 5884

    1 // 两个队列+k叉哈夫曼树 HDU 5884 2 // camp题解: 3 // 题意:nn个有序序列的归并排序.每次可以选择不超过kk个序列进行合并,合并代价为这些序列的长度和.总的合并代价不 ...

  4. 贪心算法哈夫曼编码c语言,贪心算法详解:哈夫曼编码

    理解贪心算法 贪心算法是一种算法思想,并不是一个具体的算法,因此我们用两个例子来理解什么样的问题适合用贪心算法解决. 例一 现在有一个能装 100g 物品的背包,和一些可拆分的物品(见表格),怎么装才 ...

  5. 【BZOJ4198】荷马史诗,贪心之k叉哈夫曼树

    传送门 思路: 很早以前听说过这个题 据说是一个很强的贪心(?) 然后一上来就往贪心上去想--(其实一开始知道算法不是很好,因为你不会走弯路了) 发现这玩意好像是个合并果子的模型-- 也不知道是怎么转 ...

  6. 每日四题打卡-4.15:耍杂技的牛/贪心绝对值不等式-货仓选址/贪心排序不等式-排队打水/huffman哈夫曼树-合并果子

    耍杂技的牛 具体:https://blog.csdn.net/qq_27262727/article/details/105515507 农民约翰的N头奶牛(编号为1..N)计划逃跑并加入马戏团,为此 ...

  7. 深入学习二叉树(三) 霍夫曼树

    深入学习二叉树(三) 霍夫曼树 1 前言 霍夫曼树是二叉树的一种特殊形式,又称为最优二叉树,其主要作用在于数据压缩和编码长度的优化. 2 重要概念 2.1 路径和路径长度 在一棵树中,从一个结点往下可 ...

  8. 【数据结构(25)】5.7 哈夫曼树及其应用

    文章目录 前言 一.哈夫曼树的基本概念 1. 哈夫曼树的特点 二.哈夫曼树的构造算法 1. 哈夫曼树的构造过程 2. 哈夫曼算法的实现 2.1 哈夫曼算法思路 2.2 哈夫曼算法实现 三.哈夫曼编码 ...

  9. 数据结构与算法--哈夫曼树及其应用

    一.哈夫曼树的基本概念 1) 路径: 从树中一个结点到另一个结点之间的分支构成这两个结点间的路径 2) 结点的路径长度: 两结点间路径上的分支数           3) 树的路径长度:从树根到每一个 ...

  10. 高级数据结构之赫夫曼树

    思考两个问题 电报发送:二战的时候大家都知道那时候普遍会应用电报,如果让你来设计一个电报的发送编码你该如何设计呢? 电报加密后越短越好,发送快. 破解难 解码容易 换加密树也要快 可逆的 压缩算法:给 ...

最新文章

  1. 【力扣网练习题】回文数
  2. 魔与道的反复较量 反垃圾邮件技术
  3. java jsch_java使用JSCH实现SFTP文件管理
  4. oracle 函数to_char(数据,'FM999,999,999,999,990.00') 格式化数据
  5. Spring分布式事务实现
  6. devstack安装OpenStack Pike版本 (OVS+VLAN)
  7. java图形包_java流布局图形包
  8. 前端学习(1879)vue之电商管理系统电商系统之通过axios拦截器添加token认证
  9. 无法从套接字读取更多的数据 oracle_小伙面试时被追问数据库优化,面试前如何埋点反杀?
  10. pandas.describe()参数的意义
  11. box2dweb 学习笔记--sample讲解
  12. 水性丙烯酸酯共聚物流变改性剂行业调研报告 - 市场现状分析与发展前景预测
  13. 小米手机与win10连接
  14. Metasploit---端口扫描模块
  15. COVID vaccine inequity, species swaps — the week in infographics
  16. CityMaker 8二次开发记事
  17. linux用户名不在sudoers,Ubuntu 用户名 不在 sudoers文件中,此事将被报告。
  18. CAD编辑器中CAD线型怎么修改?
  19. ajax浏览器操作发生异常,解决IE浏览器缓存导致AJAX请求数据异常
  20. FFmpeg入门详解之54:搭建环境ffmpeg

热门文章

  1. 谈谈对 GMP 的简单认识
  2. 【附源码】计算机毕业设计java智能超市导购系统设计与实现
  3. Go语言学习——基本语法
  4. ALBERT 论文+代码笔记
  5. 受疫情影响,全国多地影院密钥暂停供给,《长津湖》将面临改档
  6. linux下了搜狗怎么安装程序,【技术教程】Ubuntu如何安装搜狗输入法Linux版本(sougou_pinyin for linux)...
  7. 听别人说学习机器人哪个方向合适不重要-自己想做什么最重要
  8. ANSYS 桥梁应用笔记
  9. RHEL提示RHN没有注册问题的解决方法
  10. 山东省2022 年专升本 计算机大纲(数据库管理系统)