题目
题目来源
小Q的公司最近接到m个任务, 第i个任务需要xi的时间去完成, 难度等级为yi。
小Q拥有n台机器, 每台机器最长工作时间zi, 机器等级wi。
对于一个任务,它只能交由一台机器来完成, 如果安排给它的机器的最长工作时间小于任务需要的时间, 则不能完成,如果完成这个任务将获得200 * xi + 3 * yi收益。
对于一台机器,它一天只能完成一个任务, 如果它的机器等级小于安排给它的任务难度等级, 则不能完成。
小Q想在今天尽可能的去完成任务, 即完成的任务数量最大。如果有多种安排方案,小Q还想找到收益最大的那个方案。小Q需要你来帮助他计算一下。
思路
依然参考了牛客网大佬的思路:参考博客
主要通过结构体和sort函数,对machine和task进行排序后,进行比较计算。
相关思考
一开始有点疑惑,为什么随着任务i数量的增加,j不是从头开始计算而是从上次的位置j开始,后来明白统一进行了排序后,若该机器能够满足前面任务的时间需求(经过排序后前面任务对时间的需求更大),则必定可以满足后面的机器对时间的需求。
由此,无论是任务还是机器,都不会进行第二次计数,也就对应了题目中的,一个任务只能由一个机器完成,一个机器只能完成一个任务的条件。
代码(C++/牛客)
//安排机器
#include <bits/stdc++.h>
using namespace std;
#define LL long long
const int maxn = 1e5 + 10;
struct node{
int time,grade;
}machine[maxn],task[maxn];
int cnt[105];
int cmp(node a,node b){
if(a.time==b.time){
return a.grade>b.grade;
}
return a.time>b.time;
}
int main(){
int numMachine,numTask;
scanf("%d%d",&numMachine,&numTask);
for(int i=0;i<numMachine;i++){
scanf("%d%d",&machine[i].time,&machine[i].grade);
}
for(int i=0;i<numTask;i++){
scanf("%d%d",&task[i].time,&task[i].grade);
}
sort(machine,machine+numMachine,cmp);
sort(task,task+numTask,cmp);
// for(int i=0;i<numMachine;i++){
// printf("%d %d\n",e[i].time,e[i].grade);
// }
// for(int i=0;i<numTask;i++){
// printf("%d %d\n",f[i].time,f[i].grade);
// }
int num = 0;
LL ans = 0;
memset(cnt,0,sizeof(cnt));
int i,j,k;
for(i=0,j=0;i<numTask;i++){ //对于每个任务而言
while(j<numMachine && machine[j].time>=task[i].time){
cnt[machine[j].grade]++;
j++;
}
for(k=task[i].grade;k<=100;k++){
if(cnt[k]){
num++;
cnt[k]--;
ans = ans+200*task[i].time + 3*task[i].grade;
break;
}
}
}
printf("%d %lld\n",num,ans);
return 0;
}