题解:P10464 Task
思路
首先,要求收益最大化,且选择方式没后效性,可以很自然的想到贪心。
注意到题目中给定
排完序之后,确保了
所以我们可以维护一个 multiset,存储所有能够完成该任务的机器的等级,注意,由于
基于贪心,且 multiset 自带排序功能,我们可以二分查找第一个大于等于任务等级的机器等级,然后累加答案。
代码
#include <bits/stdc++.h>
using namespace std;
const int N=100005;
struct node
{
int x, y;
}a[N], b[N];
int n, m, cnt=0;
long long ans=0;
multiset<int> s;
multiset<int>::iterator it;
bool cmp(node a, node b)
{
if (a.x==b.x) return a.y>b.y;
return a.x>b.x;
}
int main()
{
scanf("%d%d", &n, &m);
for (int i=1; i<=n; i++) scanf("%d%d", &a[i].x, &a[i].y);
for (int i=1; i<=m; i++) scanf("%d%d", &b[i].x, &b[i].y);
sort(a+1, a+1+n, cmp);
sort(b+1, b+1+m, cmp);
int h=1;
for (int i=1; i<=m; i++)
{
for (int j=h; j<=n; j++)
{
if (a[j].x>=b[i].x)
{
s.insert(a[j].y);
h=j+1; //因为此时满足条件,下一次循环从本次循环到的数往后一个数开始循环
}
else
{
h=j; //因为此时不满足条件,下一次就从本次循环到的数开始循环
break;
}
}
it=s.lower_bound(b[i].y);
if ((it)!=(s.end()))
{
ans+=500*b[i].x+2*b[i].y;
cnt++;
s.erase(it);
}
}
printf("%d %lld", cnt, ans);
return 0;
}