CodeForces - 1089L:分配任务(贪心)

原题链接
泰泰学长养了 n 个闲人。这些闲人都懒得一笔。

今天泰泰学长有 k 个工作要分配给闲人们做。每个工作需要一个闲人做,每个闲人最多只能做一个工作。 泰泰学长让每个闲人都自由选择一个工作,第 i 个闲人选择了第 ai 个工作。

然而不幸的是,有些工作没有被选择,所以泰泰学长需要浪费口舌说服一些闲人变更自己的工作。已知第 i 个闲人需要浪费 bi 口舌,泰泰学长想知道他最少要浪费多少时间的口舌就可以完成所有工作(当然他自己是不工作的)。

Input
第一行包含两个整数 n 和 k (1≤ k ≤ n ≤ 10^5) —— n个闲人 k个工作

第二行包含 n 个整数 a1,a2,…,an (1 ≤ ai ≤ k) —— 每个闲人选择的工作

第三行包含 n 个整数 b1,b2,…,bn (1 ≤ bi ≤ 10^9) —— 说服每个闲人的时间

Output
输出最少的浪费口舌的时间。

Examples
Input
8 7
1 1 3 1 5 3 7 1
5 7 4 8 1 3 5 2
Output
10
Input
3 3
3 1 2
5 3 4
Output
0
Note
第一个样例中,说服 1, 6, 8 号闲人去做 2, 4, 6 号工作。

第二个样例,泰泰学长根本不需要浪费口舌。

题目描述

消耗尽可能少的口舌,是每个工作都有人去干

思路:贪心,每次选择浪费口舌最少的人,并且这个人所选择的工作不止他一个人去干,那么这样的人就可以去干没有人的工作,如果一个工作只有一个人,那么这个人就不能再去干别的工作

代码如下

#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
int const MAX_SIZE = 1e5+10;
struct node
{
    int job;
    int time;
};
node poe[MAX_SIZE];	//记录工人选择的工作、以及浪费口舌
int book[MAX_SIZE];	//用于记录某个工作的工人人数
bool cmp(node a, node b)
{
    if(a.time < b.time)
        return 1;
    return 0;
}
int main()
{
    int i,j,n,k,flag;	//flag用来记录已经分配的工作数量
    long long sum;
    while(~scanf("%d %d",&n,&k))
    {
        memset(book, 0, sizeof(book));
        memset(poe, 0, sizeof(poe));
        sum = flag = 0;
        for(i = 0;i < n;i++)
        {
            scanf("%d",&poe[i].job);
            if(book[poe[i].job] == 0)	//如果这个工作之前没有工人,那么就flag++
                flag++;
            book[poe[i].job]++;
        }
        for(i = 0;i < n;i++)
            scanf("%d",&poe[i].time);
        //对工人口舌时间进行排序,贪心消耗口舌最小的工人
        sort(poe, poe + n, cmp);
        int index = 0;
        //当分配工作数量达到k时,就满足条件
        while(flag < k)
        {
            int job = poe[index].job;
            //让该工作的工人去干没有工人的工作,flag++,那么该工作就要-1人
            if(book[job] > 1)
            {
                book[job]--;
                flag++;
                sum += poe[index].time;
            }
            index++;
        }
        printf("%lld\n",sum);
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_43327091/article/details/87935562