今天某公司有 M 个任务需要完成。
每个任务都有相应的难度级别和完成任务所需时间。
第 i 个任务的难度级别为 yi,完成任务所需时间为 xi 分钟。
如果公司完成此任务,他们将获得(500×xi+2×yi)美元收入。
该公司有 N 台机器,每台机器都有最长工作时间和级别。
如果任务所需时间超过机器的最长工作时间,则机器无法完成此任务。
如果任务难度级别超过机器的级别,则机器无法完成次任务。
每台机器一天内只能完成一项任务。
每个任务只能由一台机器完成。
请为他们设计一个任务分配方案,使得该公司能够最大化他们今天可以完成的任务数量。
如果有多种解决方案,他们希望选取赚取利润最高的那种。
输入格式
输入包含几个测试用例。
对于每个测试用例,第一行包含两个整数 N 和 M,分别代表机器数量和任务数量。
接下来 N 行,每行包含两个整数 xi, yi,分别代表机器最长工作时间和机器级别。
再接下来 M 行,每行包含两个整数 xi, yi,分别代表完成任务所需时间和任务难度级别。
输出格式
对于每个测试用例,输出两个整数,代表公司今天可以完成的最大任务数以及他们将获得的收入。
数据范围
1≤N,M≤100000,
0<xi<1440,
0≤yi≤100
输入样例:
1 2
100 3
100 2
100 1
输出样例:
1 50004
思路:(贪心)
防晒那道题的进阶版;
对于每个任务而言,x变化1,利润就变化500,y变化1,利润变化2,
所以x对利润影响更大,优先考虑x;
因为利润和任务密切相关,所以我们方便计算利润,给任务分配机器解决问题;
我们站在任务的视角去给任务分配机器,将任务从大到小排序,
对于每个任务,分配机器中等级>=它的等级中最小的,这样可以减少对其他机器和任务的影响;
假设任务1等级为2,任务2等级为1,机器1等级为2,机器2等级为1,要使利润最大,
任务1应该分配给机器1,这样任务2可以分配给机器2,如果任务2分配给机器1,任务1无法分配给机器2;
看不懂可以看y总讲解
解法:
从大到小,枚举每个任务,将执行时间>=它的时间的机器等级加入到一个集合,
从集合里面选等级>=它最小的一个机器;
#include<iostream>
#include<algorithm>
#include<set>
using namespace std;
const int N=1e5+10;
pair<int,int> mch[N],task[N];//mch表示机器,task表示任务;
int main()
{
int n,m;
while(cin>>n>>m){
for(int i=0;i<n;++i) cin>>mch[i].first>>mch[i].second;
for(int i=0;i<m;++i) cin>>task[i].first>>task[i].second;
sort(mch,mch+n);//降序排序
sort(task,task+m);//降序排序
multiset<int>st;//multiset表示值可重复的集合;
long long res=0,cnt=0;
for(int i=m-1,j=n-1;i>=0;i--){//升序从后往前枚举任务,i表示任务编号,j表示机器;
int x=task[i].first,y=task[i].second;
while(j>=0&&mch[j].first>=x) st.insert(mch[j--].second);//将工作时间>=任务时间的机器的等级加入集合;
auto it=st.lower_bound(y);//寻找>=任务等级中最小的;
if(it!=st.end()){
cnt++;//计算任务数量
res+=x*500+y*2;//计算利润;
st.erase(it);//用过的机器就删除;
}
}
cout<<cnt<<' '<<res<<endl;
}
return 0;
}