2020牛客国庆集训派对day6 F Lazyland(贪心/优先队列)

题目描述

The kingdom of Lazyland is the home to n idlers. These idlers are incredibly lazy and create many problems to their ruler, the mighty King of Lazyland.

Today k important jobs for the kingdom (kn) should be performed. Every job should be done by one person and every person can do at most one job. The King allowed every idler to choose one job they wanted to do and the i-th idler has chosen the job ai.

Unfortunately, some jobs may not be chosen by anyone, so the King has to persuade some idlers to choose another job. The King knows that it takes *bi* minutes to persuade the *i-th idler. He asked his minister of labour to calculate the minimum total time he needs to spend persuading the idlers to get all the jobs done. Can you help him?*

输入描述:

The first line of the input contains two integers n and k (1 ≤ k ≤ n ≤ 105) — the number of idlers and the number of jobs.
The second line of the input contains n integers a1, a2, …, an (1 ≤ ai ≤ k) — the jobs chosen by each idler.

The third line of the input contains n integers b1, b2, …, bn (1 ≤ bi ≤ 109) — the time the King needs to spend to persuade the i-th idler.

输出描述:

The only line of the output should contain one number — the minimum total time the King needs to
spend persuading the idlers to get all the jobs done.

示例1

输入

复制

8 7
1 1 3 1 5 3 7 1
5 7 4 8 1 3 5 2

输出

复制

10

说明

In the first example the optimal plan is to persuade idlers 1, 6, and 8 to do jobs 2, 4, and 6.

示例2

输入

复制

3 3
3 1 2
5 3 4

输出

复制

0

大意是说现在有k项任务和n个(n >= k),每个人都会选择一件任务,然而有的任务可能没人做,就需要劝一些人换任务(花费b[i]的时间),问使得所有任务都有人做所要花费的最小劝说时间是多少。

开数组记录,choose[i]表示做第i件任务的b[i]最大的人的b[i],当遍历到当前的人时,如果他选择的任务没人做的话就直接赋值,已经有人做的话就比较b[i]的大小,如果当前的人的b[i]更大,就直接替换掉(贪心地优先选择b[i]大的人,劝说剩下的人),把之前的人的b[i]加入优先队列;如果更小的话就直接加入优先队列。最后对于所有没覆盖到的任务,从优先队列弹出队首累加答案即可。

#include <iostream>
#include <queue>
using namespace std;
int a[100005], b[100005];
priority_queue<int, vector<int>, greater<int> > q;
int choose[100005];//choose[i]表示选择第i个工作的人劝说他所花费的时间(所有里面最长的)
int main()
{
	//freopen("data.txt", "r", stdin);
	int n, k;
	cin >> n >> k;
	for(int i = 1; i <= n; i++) cin >> a[i];
	for(int i = 1; i <= n; i++) cin >> b[i];
	for(int i = 1; i <= n; i++)
	{
		if(!choose[a[i]]) choose[a[i]] = b[i];
		else if(choose[a[i]] <= b[i])
		{
			q.push(choose[a[i]]);
			choose[a[i]] = b[i];
		}
		else q.push(b[i]);
	}
	long long ans = 0;
	for(int i = 1; i <= k; i++)
	{
		if(!choose[i])
		{
			long long now = 1ll * q.top();
			ans += now;
			q.pop();
		}
	}
	cout << ans ;
	return 0;
}
原文地址:https://www.cnblogs.com/lipoicyclic/p/13775722.html