题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4864
题目大意:
有N个机器,M个任务。
其中每个机器有xi,yi。(xi表示每台机器的最长工作时间,yi表示机器可以完成的任务难度值)
每个任务有xi,yi。(xi表示完成该任务需要的时间,yi表示任务的难度)每完成一个任务,可以得到一笔钱:500 * xi + 2 * yi。
一台机器最多只能做一个任务,一个任务最多只能被完成一次。
问:最多能完成几个任务,且在完成任务最多的情况下,能得到钱数最多为多少。
解题思路:
贪心的想法。将机器和任务按照一下规则排序:
如果xi不同,按照xi的大小从大到小排序;
如果xi相同,yi不同,按照yi的大小从大到小排序;
如果上述均相同,则按照机器排在任务前面。
经过排序之后,就保证了前面的 x 值一定比后面的 x 值大,只需要比较 y 值即可。遍历一次,如果碰到机器,则将 y 值存进一个multiset里面。如果碰到任务,那么在multiset里面找一个最小的不小于 yi 的值,用该机器去完成该任务。
代码:
using namespace std;
typedef long long ll;
struct node {
int x, y, type;
} a[200010];
int n, m;
bool cmp(node s, node v) {
if (s.x != v.x) return s.x > v.x;
if (s.y != v.y) return s.y > v.y;
if (s.type != v.type) return s.type > v.type;
}
multiset<int> s;
multiset<int> :: iterator it;
int main () {
int x, y, cnt = 0;
while(~scanf("%d%d", &n, &m)) {
cnt = 0;
for (int i = 0; i < n; i++) {
scanf("%d%d", &a[cnt].x, &a[cnt].y);
a[cnt++].type = 1;
}
for (int i = 0; i < m; i++) {
scanf("%d%d", &a[cnt].x, &a[cnt].y);
a[cnt++].type = 0;
}
sort(a, a + cnt, cmp);
ll ans = 0;
ll t = 0;
s.clear();
for (int i = 0; i < cnt; i++) {
if (a[i].type == 1) s.insert(a[i].y);
else {
if(!s.empty()) {
it = s.lower_bound(a[i].y);
if (it == s.end()) continue;
t++;
ans += a[i].y * 2 + 500 * a[i].x;
s.erase(it);
}
}
}
printf("%I64d %I64d\n", t, ans);
}
return 0;
}