要求:有n台机器和m个任务,并且每台机器和每个任务都带有一个时间标记和一个等级标记,只有机器的两个标记都大于任务时才能进行该任务。最大等级不超过100,完成一个任务获得钱数为500*时间+2*等级。一台机器一天只能完成一个任务,求完成最大任务数,若有多解,取赚钱数最多的。
方法:贪心。注意T。
1.因为钱数的算式和等级的范围表明,时间为优先考虑项,若任务A的时间比B长,那么A的赚钱数一定比B多。
2.将任务按时间从大到小排序,时间相同时等级从大到小排序。将机器按时间从大到小排序。
3.贪心逻辑是:按照任务顺序已是钱数最多的策略,因此需要选用尽可能小的等级数,较大的等级数机器供其他任务使用。
4.伪代码如下:
for(遍历各个任务)
{
while(找到时间不小于任务的所有机器)//机器
{
用s数组存储等级;
}
for(从当前任务的等级到100遍历各个等级)//等级
{
若s数组存有这个等级,则计数并钱加上。
}
}
#include<algorithm>
#include<string.h>
#include<stdio.h>
using namespace std;
struct machine
{
int time1,level;
};
struct task
{
int x,y;
};
machine machines[100005];
task tasks[100005];
bool cmp1(machine c,machine d)
{
return c.time1>d.time1;
}
bool cmp2(task a,task b)
{
if(a.x>b.x) return 1;
else if(a.x<b.x) return 0;
else return a.y>b.y;
}
int main()
{
int i,j,k,n,m,cnt,s[200];
long long money;
while(scanf("%d%d",&n,&m)!=EOF)
{
cnt=0,money=0;
memset(s,0,sizeof(s));
for(i=0;i<n;i++)
{
scanf("%d%d",&machines[i].time1,&machines[i].level);
}
for(i=0;i<m;i++)
scanf("%d%d",&tasks[i].x,&tasks[i].y);
sort(machines,machines+n,cmp1);
sort(tasks,tasks+m,cmp2);
j=0;
for(i=0;i<m;i++)
{
while(j<n&&machines[j].time1>=tasks[i].x)
{
s[machines[j].level]++;
j++;
}
for(k=tasks[i].y;k<=100;k++)
{
if(s[k]>0)
{
s[k]--;
cnt++;
money+=(500*tasks[i].x+2*tasks[i].y);
break;
}
}
}
printf("%d %lld\n",cnt,money);
}
}