[腾讯] 安排机器

小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:

1 2
100 3
100 2
100 1

 

输出例子1:

1 20006

 

详解:按照时间和等级降序,这样保证取到的一定是收益最大的解(因为时间的收益严格大于等级,所以时间作为第一关键字,如果能完成收益大的任务,自然不会去完成收益低的任务);然后在此基础上,加所有工作时间大于等于任务的机器加入multiset中,取出等级最接近任务等级的,且大于等于任务等级的,就是lower_bound,这样可以保证完成的任务一定是最多的,不会遗漏。(因为任务和机器都按照时间进行过排序,那么在set中机器的时间一定是可以完成后续任务的,它们是被时间更长的任务选择进来的,所以在此不需要考虑机器的工作时间了,在后面他们的时间不会有区别都是一样的,为了防止后面出现等级更大的任务,那么肯定要选择等级刚好大于任务的机器了),这样两次贪心下来得到的就是一定是最优解了,而且第二次贪心可以二分。

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
using namespace std;
 
struct node
{
    int x;
    int y;
};
 
int cmp(node a, node b)
{
    if (a.x == b.x)
        return a.y > b.y;
    return a.x > b.x;
}
 
int main()
{
    int n, m;
    int num = 0;
    long long profit = 0;
    vector<node > machine(n);
    vector<node > job(m);
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; ++i)
    {
        scanf("%d%d", &machine[i].x, &machine[i].y);
    }
    for (int i = 0; i < m; ++i)
    {
        scanf("%d%d", &job[i].x, &job[i].y);
    }
    sort(machine.begin(), machine.end(), cmp);
    sort(job.begin(), job.end(), cmp);
    vector<int> cnt(105, 0);
    for (int i = 0, j = 0; i < m; ++i)
    {
        while (j < n && machine[j].x >= job[i].x)
        {
            cnt[machine[j].y]++;
            j++;
        }
        for (int k = job[i].y; k <= 100; ++k)
        {
            if (cnt[k])
            {
                ++num;
                cnt[k]--;
                profit += 200 * job[i].x + 3 * job[i].y;
                break;
            }
        }
    }
    cout << num << "  " << profit << endl;
    return 0;
}

 

 

#include <iostream>
#include <string>
#include <vector>
#include <algorithm>

#include <bits/stdc++.h>
using namespace std;
 
const int maxn = 100005;
struct node {
    int time, priority;
}machine[maxn], task[maxn];
int cnt[105];
int cmp(node a ,node b){
    if(a.time == b.time)return a.priority > b.priority;
    return a.time > b.time;
}
int main(){
    int n,m;
    scanf("%d%d",&n,&m);
    for(int i = 0;i < n;i++) scanf("%d%d",&machine[i].time, &machine[i].priority);
    for(int i = 0;i < m;i++) scanf("%d%d",&task[i].time, &task[i].priority);
    sort(machine, machine + n,cmp);
    sort(task, task + m,cmp);
    int num = 0;
    long long ans = 0;
    memset(cnt,0,sizeof(cnt));
    int i,j,k;
    for(i = 0,j = 0;i < m;i++){
        while(j < n && machine[j].time >= task[i].time){
            cnt[machine[j].priority]++;
            j++;
        }
        for(k = task[i].priority;k <= 100;k++){
            if(cnt[k]){

                num++;
                cnt[k]--;
                ans = ans + 200 * task[i].time +3 * task[i].priority;
                break;
            }
        }
    }
    
    printf("%d %lld\n",num,ans);
    return 0;
}

 

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值