蓝桥杯练习题:小明染衣服
核心算法:哈夫曼树(带权路径长度最短的二叉树)
小明买了 n 件白色的衣服,他希望对这些衣服进行染色,每次染色时,他会将某种颜色的所
有衣服寄去染色厂,第 i 件衣服的邮费为 ai 元,染色厂会按照小明的要求将其中一部分衣
服染成同一种任意的颜色,之后将衣服寄给小明,请问小明要将 n 件衣服染成不同颜色的最
小代价是多少?
输入格式
第一行输入一个整数 n,表示衣服的数量。第二行输入 n 个整数 a1,a2,……an,表示第 i 件衣服的邮费为 ai 元。
输出描述
输出一个整数表示小明所要花费的最小代价
样例输入 1
5
5 1 3 2 1
样例输出
25
样例输入 2
5
4 5 3 3 7
样例输出 2
50
样例输入 3
12
8 9 3 4 1 100 5 20 23 18 34 67
样例输出 3
819
相信很多备赛蓝桥杯的UU都遇到过这道题,这道题对于熟练掌握哈夫曼树的master是小菜一碟,但是对于很多事前没有接触过哈夫曼树的同学肯定有一定难度,而笔者发现网上的大多数解析只给出了代码和简单的介绍,因此笔者写下这篇文章,希望可以帮到有需要的伙伴。
哈夫曼树(带权路径长度最短的二叉树)
路径长度:从根节点到该节点路径上所包括的数目。(对树也不了解的朋友可以去查一下相关资料,在此笔者不再赘述)。
节点的权和带权路径长度
若将树中节点赋给一个有着某种含义的数值,则这个数值称为该节点的权。节点的带权路径为:从根节点到该节点之间的路径长度与该节点的权的乘积。
就本体的样例2为模板介绍:
如图所示
现在我们已经具备了足够的知识了,可以来解决这道题了。
解析:1.每次可以将同一种颜色的所有衣服寄过去,会将其中一部分衣服染成同一种任意颜色(寄出一种颜色的衣服,收回两种颜色的衣服,一分为二),由这两个条件可知是一个一分为二的选择模型,因而可以想到二叉树模型。
2.规定了衣服的件数(叶节点个数)和每件衣服的价格(权),目的要求最小代价(带权路径长度最短),因此想到哈夫曼树(带权路径长度最短的二叉树)
python蓝桥杯的资源是如此的稀缺(相比c/c++),本题解析网上给出的基本上用了queue模块中的PriorityQueue函数,鉴于许多朋友对queue队列库并不熟悉,因此笔者在此给出简单的基础版代码!
n=int(input())
list=list(map(int,input().split()))
list.sort()
sum=0
for i in range(n-1):
if(len(list)>1):
t=list.pop(0)+list.pop(0) #pop()函数在弹出元素后,列表元素数立马-1,因此不要写成pop(0)+pop(1)
sum+=t
list.append(t)
list.sort()
print(sum)
每一个不曾起舞的日子,都是对生活的辜负! —尼采