HDU-4864-Task
这是一道贪心题目哦~
题目大意:给你几台机器,给你几个任务,每台机器有自己限制的工作时长和自己的等级,每个任务也有完成所需的工作时长和自己的等级,一台机器如果想要解决一个任务,必须满足这台机器对应的等级大于等于这个任务对应的等级,这台机器对应的工作时长也需要大于等于这个任务的工作时长,并且每台机器每天只能处理一项任务,一台机器处理完一项任务所获得的利润是500工作时长+2工作等级。问一天可以获得的最大利润是多少。
本题思路:很明显,是一道贪心,我们把时长和等级保存在结构体当中,然后排序,把工作时长长的放在前面,也就是降序,等级高的也放在前面,也是降序,因为每一台机器一天只能处理一个工作嘛,于是我们可以尽可能的找任务和机器时长和等级相匹配的结合在一起,之后的任务(因为是降序),于是那些等级高的机器也是可以完成的,我们用s[]数组记录:下标记录机器的等级,如果s[] > 0,那么就代表有任务可以处理。
判断条件:j < n && ma[j].x >= tas[i].x;
j代表机器遍历,我们把先开始把所以可以处理难搞的任务的机器记录下来,储存在s[]数组当中。然后到选择一台合适的机器处理当前任务,我们就从当前任务相同的等级开始,一直往上遍历,如果s[] > 0,就代表可以处理该任务,我们这里不需要担心时间问题,因为时间都是按照降序处理的,只要s[] > 0,那么说明前面有任务的时间小于等于机器的时间,我们就不需要担心。
这样维护一个ans就行啦~
这就是可以获得最大的利润啦~
代码部分:
#include <bits/stdc++.h>
#define mst(a, n) memset(a, n, sizeof(a))
using namespace std;
typedef long long ll;
const int N = 1e5 + 10;
struct node
{
int x, y;
bool operator< (const node& r) const
{
if (x != r.x)
{
return x > r.x;
}
else
{
return y > r.y;
}
}
}ma[N], tas[N];
int n, m;
int s[N];
int main()
{
while (scanf ("%d%d", &n, &m) == 2)
{
for (int i = 0; i < n; i++)
{
scanf ("%d%d", &ma[i].x, &ma[i].y);
}
for (int i = 0; i < m; i++)
{
scanf ("%d%d", &tas[i].x, &tas[i].y);
}
sort(ma, ma + n);
sort(tas, tas + m);
int num = 0;
ll ans = 0;
mst(s, 0);
int j = 0;
for (int i = 0; i < m; i++)
{
while (j < n && ma[j].x >= tas[i].x)
{
s[ma[j].y]++;
j++;
}
for (int k = tas[i].y; k <= 100; k++)
{
if (s[k] > 0)
{
num++;
s[k]--;
ans += 1ll * (500 * tas[i].x + 2 * tas[i].y);
break;
}
}
}
cout << num << " " << ans << endl;
}
return 0;
}