📜  QA – 安置测验|工作和工资|问题 12(1)

📅  最后修改于: 2023-12-03 15:34:33.667000             🧑  作者: Mango

QA – 安置测验|工作和工资|问题 12

问题描述

在安置测验中,一个人的工作是将其他人分配到不同的位置。将一个人分配到一个位置需要一定的时间和费用,因此工资将随着分配的人数增加而增加。给定一个测验者的排名历史,以及每个人分配到不同位置所需的费用,求该测验者的工资。

输入格式

输入的第一行包含两个整数 $N$ 和 $M$,表示安置测验者的数量和位置的数量。

接下来 $N$ 行,每行包含一个整数 $rank_i$,表示排名历史中排在第 $i$ 位的测验者的排名。

接下来 $M$ 行,每行包含一个整数 $cost_i$,表示将一个人分配到位置 $i$ 需要的费用。

输出格式

输出一个整数,表示该测验者的工资。

输入样例
5 3
5
1
2
4
3
2
3
1
输出样例
29
说明

样例输入中,测验者排名历史为 5 1 2 4 3,费用分别为 2、3 和 1。将这 5 个人分配到不同的位置,需要的费用分别为 2+1、3、1+4、0 和 2+3。因此,该测验者的工资为 2+1+4+0+3=10+19=29。

算法思路

可以将测验者排名历史按照从小到大的顺序排序,从排名最小的开始依次分配位置。为了尽可能地减少费用,每次应该选择费用最小的位置进行分配。

具体实现时,我们可以使用一个小根堆来维护当前所有可以分配的位置,每次选择堆顶的位置进行分配。在分配了一个人之后,更新该位置的费用(即将其从堆中删除,并将费用加上原先的费用即可)。

代码实现
import heapq

n, m = map(int, input().split())
rank = [int(input()) for _ in range(n)]
cost = [int(input()) for _ in range(m)]

# 将测验者排名历史排序
rank.sort()

# 使用一个小根堆来维护当前所有可以分配的位置
h = [(cost[i], i) for i in range(m)]
heapq.heapify(h)

ans = 0
for r in rank:
    c, i = heapq.heappop(h)  # 选择费用最小的位置
    ans += c  # 将费用累加到工资中
    cost[i] += c  # 更新所选位置的费用
    heapq.heappush(h, (cost[i], i))  # 将更新后的位置加入小根堆中供下次分配使用

print(ans)