NC235294 任务

题目

  • 原题地址:任务
  • 题目编号:NC235294
  • 题目类型:set、贪心
  • 时间限制:C/C++ 1秒,其他语言2秒
  • 空间限制:C/C++ 262144K,其他语言524288K

1.题目大意

  • \(n\) 个任务,\(m\) 台机器,每个任务和每台机器都有 \(x\)\(y\),分别代表完成所需的时间/工作的最大时间和难度等级
  • 一台机器只能执行一个任务,并且满足工作的最大时间大于等于完成所需的时间,机器的等级要大于等于任务的等级
  • 对于第 \(i\) 个任务有 \(x_i\)\(y_i\),完成该任务就可以获得 \(500∗x_i+2∗y_i\) 的报酬
  • 求最多能完成的任务数量以及最大的报酬

2.题目分析

  • 先对任务和机器排序,时间大的在前面,时间相同的等级高的在前面
  • 对于每个任务,先选出时间大于该任务的机器,再选择选出的机器中等级不低于该任务的最低等级的机器进行匹配,随后从集合中去掉该机器
  • 由于已经排序(时间大的在前面),所以可以保证前面的任务选出的机器的时间一定大于后面的机器,所以集合中只需要存储等级即可
  • 需要注意这里使用的是multiset,它可以保证元素有序并且元素可以重复
  • 如果用set的话,匹配完一个机器会去掉集合中该机器对应的等级,由于同一等级的机器可能不止一个,并且我们只存储等级,所以每次匹配后去掉的是选中的机器中所有等级为匹配等级的机器,这显然是不合理的

3.题目代码

#include <bits/stdc++.h>

using namespace std;

typedef struct ma {
    int x, y;
    bool operator< (const ma &p) const { return x==p.x?y>p.y:x>p.x;}
} ma;

int main() {
    int n, m;
    cin >> n >> m;
    ma a[n], b[m];
    for(int i=0;i<n;i++) cin >> a[i].x >> a[i].y;
    for(int i=0;i<m;i++) cin >> b[i].x >> b[i].y;
    sort(a, a+n);
    sort(b, b+m);
    multiset<int> ms;
    long long cnt = 0, ans = 0;
    for(int i=0,j=0;i<m;i++) {
        while(j<n&&b[i].x<=a[j].x) ms.insert(a[j++].y);
        auto it = ms.lower_bound(b[i].y);
        if(it!=ms.end()) cnt++, ans += 500*b[i].x + 2*b[i].y, ms.erase(it);
    }
    cout << cnt << ' ' << ans << endl;
}
posted @ 2022-08-31 08:58  仪战群儒  阅读(70)  评论(0)    收藏  举报