题意:
有n个机器,m个任务,n,m<=100000,每个机器都有工作时间的最大限制xi和完成的最大难度yi,每个任务也有所需要的时间和难度,只要机器的时间大于等于任务,难度大于等于任务,该任务就可以被机器完成,每完成一个任务就可以得到500*xi+2*yi的money,问最多能有多少个任务被完成,并且保证完成任务数量最多的情况下,所得到的money最多是多少?
题解:
根据公式,500*xi+2*yi,我们可以得知影响money最多的是xi时间,所以我们可以先从小到大排序x,如果x相同再排序y(一样从小到大),排序完之后就用任务的时间来找到所有符合条件的机械,再从中找到最近接任务等级的机械,即可。如果你找到比任务x,y大的机械就直接计算的话,就会出错。(如果这点想不通的话,你可以想一下,下面这组数据):
2 2
150 5
102 2
100 3
101 1
那后面加进来的任务会不会无法使用符合上一个任务条件但是没被用到的机械呢?不会,因为任务是按时间降序排列的,符合上一个任务的机械组肯定符合下一个任务。
题外话:想到了先排序x再排序y,但是就是没想到要先存放符合条件的机械组,再进行选取,可惜。
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN=100000+7;
struct node
{
int x,y;
}task[MAXN],ma[MAXN];
int mark[MAXN];
bool cmp(node a,node b)//先排序影响因素最大的x时间,再排序y等级
{
if(a.x==b.x)
return a.y>b.y;
else
return a.x>b.x;
}
int main()
{
int n,m,i,j;
while(~scanf("%d%d",&n,&m))
{
memset(mark,0,sizeof(mark));
for(i=1;i<=n;i++)
scanf("%d%d",&ma[i].x,&ma[i].y);
for(i=1;i<=m;i++)
scanf("%d%d",&task[i].x,&task[i].y);
sort(task+1,task+1+m,cmp);
sort(ma+1,ma+1+n,cmp);
// for(i=1;i<=m;i++)
// printf("%d %d\n",task[i].x,task[i].y);
long long int sum=0;
int ans=0;
for(i=1,j=1;i<=m;i++)
{
while(j<=n&&ma[j].x>=task[i].x)//找到所有大于任务时间的机械。
{
mark[ma[j].y]++;
j++;
}
for(int k=task[i].y;k<=100;k++)//等级最大是100,然后找到与任务等级最接近的机械
if(mark[k])
{
mark[k]--;
sum+=500*task[i].x+task[i].y*2;
ans++;
break;
}
}
printf("%d %lld\n",ans,sum);
}
}