题目:545谈判

题目描述

在很久很久以前,有 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])  
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值