题目大意:N个机器和M个任务, 每个任务有两个值花费时间xi和难度yi, 每个机器也有两个值最大工作时间xj和最大工作难度yj, 机器可以胜任某个工作的条件是xi>=xj 并且 yi>=yj,机器胜任一个工作可以拿到xj*500+2*yj的钱,现在问你怎么匹配才能使匹配数最大且钱数最多。
( 1<=N,M<=100000 ,0< xi,xj< 1440,0<=yi,yj<=100)
还是一道很有意思的贪心题。
首先发现x的贡献大,那么机器和任务都按照x从大到小排序,如果相同再按y排序。然后我们可以借用田忌赛马的思想,对于所有xi>=xj的机器,我们从中选yi最小的机器,这样我们就可以使得更多机器来完成后面的任务。
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=100010;
struct node
{
int x,y;
}a[maxn],b[maxn];
bool cmp(node a,node b){if(a.x!=b.x) return a.x>b.x; else return a.y>b.y;}
int tmp[maxn];
int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1;i<=n;i++) scanf("%d%d",&a[i].x,&a[i].y);//机器
for(int i=1;i<=m;i++) scanf("%d%d",&b[i].x,&b[i].y);//工作
sort(a+1,a+n+1,cmp);
sort(b+1,b+m+1,cmp);
int cnt=0; ll sum=0;
memset(tmp,0,sizeof(tmp));
for(int i=1,j=1;i<=m;i++)
{
while(j<=n && a[j].x>=b[i].x)
{
tmp[a[j].y]++;
j++;
}
for(int k=b[i].y;k<=100;k++)
{
if(tmp[k])
{
tmp[k]--;
cnt++;
sum+=500*b[i].x+2*b[i].y;
break;
}
}
}
printf("%d %I64d\n",cnt,sum);
}
return 0;
}