安排机器

题目:

小Q的公司最近接到m个任务, 第i个任务需要xi的时间去完成, 难度等级为yi。
小Q拥有n台机器, 每台机器最长工作时间zi, 机器等级wi。
对于一个任务,它只能交由一台机器来完成, 如果安排给它的机器的最长工作时间小于任务需要的时间, 则不能完成,如果完成这个任务将获得200 * xi + 3 * yi收益。

对于一台机器,它一天只能完成一个任务, 如果它的机器等级小于安排给它的任务难度等级, 则不能完成。

小Q想在今天尽可能的去完成任务, 即完成的任务数量最大。如果有多种安排方案,小Q还想找到收益最大的那个方案。小Q需要你来帮助他计算一下。

输入描述:

  • 输入包括N + M + 1行,
  • 输入的第一行为两个正整数n和m(1 <= n, m <= 100000), 表示机器的数量和任务的数量。
  • 接下来n行,每行两个整数zi和wi(0 < zi < 1000, 0 <= wi <= 100), 表示每台机器的最大工作时间和机器等级。
  • 接下来的m行,每行两个整数xi和yi(0 < xi < 1000, 0 <= yi<= 100), 表示每个任务需要的完成时间和任务的难度等级。

输出描述:

  • 输出两个整数, 分别表示最大能完成的任务数量和获取的收益。

示例:

输入:

1 2
100 3
100 2
100 1

输出:

1 20006

思路:

1、对机器和任务都分别进行排序:时间从大到小,时间相同的按照等级由大到小(cmp完成)

2、对每一个任务进行循环:(第一个 for 循环)

第一个 while 找到 时间上能够处理当前任务的机器(先忽略等级要求),并将每个满足条件的机器都存储起来。

第二个 for 循环,看等级上,这些存储的机器能否处理相应的任务,因while循环已经保证了时间上的可操作性

注意:一共三个循环

代码:

#include <set>
#include <algorithm>
#include <vector>
#include <iostream>
using namespace std;
typedef long long ll;
int main()
{
    int n, m;
    cin >> n >> m;
    vector<pair<int, int>> machine(n);
    for (auto &e : machine) cin >> e.first >> e.second;
 
    vector<pair<int, int>> task(m);
    for (auto &e : task) cin >> e.first >> e.second;
 
    sort(task.begin(), task.end());
    sort(machine.begin(), machine.end());
 
    ll ans = 0, cnt = 0;
 
    multiset<int> level;
 
    int j = n - 1;
 
    for (int i = m - 1; i >= 0; --i)
    {
        while (j >= 0 && machine[j].first >= task[i].first)
        {
            level.insert(machine[j].second);
            j--;
        }
        if (!level.empty())
        {
            auto it = level.lower_bound(task[i].second);
            if (it != level.end())
            {
                ans += 200 * task[i].first + 3 * task[i].second;
                level.erase(it);
                cnt++;
            }
        }
    }
    cout << cnt << " " << ans << endl;
    return 0;
}

题目来源:https://www.nowcoder.com/questionTerminal/42e7ff5c5696445ab907caff17fc9e15

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值