题目描述
在很久很久以前,有 n 个部落居住在平原上,依次编号为 1 到 n。第 i 个部落的人数为 ti。有一年发生了灾荒。年轻的政治家小蓝想要说服所有部落一同应对灾荒,他能通过谈判来说服部落进行联合。每次谈判,小蓝只能邀请两个部落参加,花费的金币数量为两个部落的人数之和,谈判的效果是两个部落联合成一个部落(人数为原来两个部落的人数之和)。
输入描述
输入的第一行包含一个整数 n,表示部落的数量。第二行包含 n 个正整数,依次表示每个部落的人数。其中,1≤n≤1000,1≤ti≤10^4。
输出描述
输出一个整数,表示最小花费。
4
9 1 3 5
31
题目分析(贪心):
题目中有n个部落,每个部落有ti个人,可以画图理解:
根据题目意思可知,要将部落合并,花费的金币数量为两个部落的人数之和,因此代价就是两个部落的人数和。
举个例子:先将1、9合并,花费为(1+9)=10。再将3合并,花费(1+9+3)=13,最后合并5,花费(1+9+3+5)=18。因此,合并的顺序是1、9、3、5,总花费为(1+9+1+9+3+1+9+3+5)=41
由此可得,越早合并的部落,要计算的次数就越多。所以使用贪心算法:人数越少的部落,需要越早进行合并,这样花费在总花费之中是最低的。所以,人数越少的部落越早合并越好,人数越多的部落越晚合并越好。
我们需要将部落的人数存入队列,按照升序排序(从小到大),每次取出两个部落进行合并。
所以我们可以使用前缀和来计算,仍然用上面那个例子,前缀和计算的是(1+1+9+1+9+3+1+9+3+5)=42,根据题意,在合并部落的时候才需要花费,所以要去掉前缀和中的首元素1,显现在代码中就是减掉第一个元素a[0]。
AC代码(Python):
import os
import sys
# 请在此输入您的代码
##使用 itertools 库中的 accumulate 计算前缀和的函数
from itertools import accumulate
i = int(input())
#将输入的整数列表排序
a = sorted(list(map(int,input().split())))
#计算并输出前缀和-a[0]
print(sum(list(accumulate(a))) - a[0])