一.题目链接:
HDU-4864
二.题目大意:
有 n 个机器,每个机器有 x,y.
有 m 个任务,每个任务有 x,y.
当且仅当机器的 x,y 均大于 任务的 x,y 时,该任务才可被完成,并获得金额 500x + 2y.
每个机器最多可处理一个任务.
求最多能处理的任务数,在此条件下,求出最大金额.
三.分析:
一个任务的 x 造成的最小收益为 500,y 造成的最大收益为 200.
因此,应尽可能使 x 大的任务被完成,在此情况下,使 y 尽可能大的任务被完成.
对机器和任务排序( x 从大到小,x 相同时,y 从大到小)
对于任务 i,如果机器 j 的 x 大于等于任务 i 的 x,那么 1 ~ j 机器的 x 均大于等于任务 i 的 x.
对于任务 i,如果机器 j 的 x 小于任务 i 的 x,那么 1 ~ j 机器的 x 均小于任务 i 的 x.
所以说只需要找到不满足任务 i 的 x 的第一个机器 j
则机器 1 ~ j - 1 的 x 均大于 任务 i ~ m 的 x.
因此,只需找出机器 1 ~ j - 1 中 y 大于等于任务 i 的 y 的第一个,即为最优解.
ps:一开始这里想用二分查找位置的,可这样 y 值无法记录,之后需要遍历,结果就 TLE...
四.代码实现:
#include <set>
#include <map>
#include <ctime>
#include <queue>
#include <cmath>
#include <stack>
#include <bitset>
#include <vector>
#include <cstdio>
#include <sstream>
#include <cstring>
#include <cstdlib>
#include <iostream>
#include <algorithm>
#define eps 1e-8
#define lc k * 2
#define rc k * 2 + 1
#define pi acos(-1.0)
#define ll long long int
using namespace std;
const int M = (int)1e5;
const ll mod = (ll)1e9 + 7;
const int inf = 0x3f3f3f3f;
int n, m;
struct node
{
int x, y;
}ma[M + 5], ta[M + 5];
int cnt[M + 5];
bool cmp(node a, node b)
{
if(a.x != b.x)
return a.x > b.x;
return a.y > b.y;
}
int main()
{
while(~scanf("%d %d", &n, &m))
{
memset(cnt, 0, sizeof(cnt));
for(int i = 1; i <= n; ++i)
scanf("%d %d", &ma[i].x, &ma[i].y);
for(int i = 1; i <= m; ++i)
scanf("%d %d", &ta[i].x, &ta[i].y);
sort(ma + 1, ma + n + 1, cmp);
sort(ta + 1, ta + m + 1, cmp);
int num = 0;
ll money = 0;
for(int i = 1, j = 1; i <= m; ++i)
{
while(j <= n && ma[j].x >= ta[i].x)
{
cnt[ma[j].y]++;
j++;
}
for(int k = ta[i].y; k <= 100; ++k)
{
if(cnt[k])
{
num++;
cnt[k]--;
money += 500ll * ta[i].x + 2 * ta[i].y;
break;
}
}
}
printf("%d %lld\n", num, money);
}
return 0;
}