题意:
有n台机器,m个任务,每台机器有xi,yi,每个任务也有xj,yj,当一个任务可以被处理的条件是,xj<=xi 且 yj<yi,处理完产生 500*xj+2*yj 的价值,问你最多产生的价值是多少?
贪心的话,如果是遍历任务的话,那么我们希望尽可能做时间和level更高的任务,我们可以先按时间排,时间相同按level,递增排,机器也是按这个排。
然后从最大价值的任务开始遍历,对于每一个任务,找到第一个大于等于任务【i】.x的机器,然后显然就是在包括这台机器以后的所有机器里找出一个level最小(但大于等于任务)的机器咯。
那么只需要把 这台机器到最后一台机器丢进set里,然后按level排序,每次二分找到那个我们要找的机器,然后erase掉即可。
当然下次再把机器丢进set里的时候只需要丢到上一次最后一台即可。这样保证了set这部分的复杂度是严格的nlogn咯。
所以总复杂度是m+nlogn咯
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <algorithm>
#include <queue>
#include <map>
#include <set>
#include <vector>
#include <iostream>
using namespace std;
const double pi=acos(-1.0);
double eps=0.000001;
__int64 max(__int64 a,__int64 b)
{return a>b?a:b;}
__int64 min(__int64 a,__int64 b)
{return a<b?a:b;}
struct node
{
__int64 x,y;
node(){}
node(__int64 a,__int64 b)
{x=a,y=b;}
bool operator<(const node&bb) const
{
return y<bb.y;
}
};
node ren[100005],mm[100005];
bool cmp(node a,node b)
{
if (a.x!=b.x)
return a.x<b.x;
return a.y<b.y;
}
bool cmp_bin(node a,node b)
{return a.x<b.x;}
multiset<node> sb;
int main()
{
__int64 i,j;
__int64 x,y;
__int64 n,m;
while( scanf("%I64d%I64d",&n,&m)!=EOF)
{
sb.clear();
for (i=1;i<=n;i++)
scanf("%I64d%I64d",&ren[i].x,&ren[i].y);
for (i=1;i<=m;i++)
scanf("%I64d%I64d",&mm[i].x,&mm[i].y);
sort(ren+1,ren+1+n,cmp);
sort(mm+1,mm+1+m,cmp);
__int64 cun=0;
__int64 ans=0;
__int64 last=n;
for (i=m;i>=1;i--)
{
__int64 it=lower_bound(ren+1,ren+1+n,mm[i],cmp_bin)-ren;
if (it==n+1) continue;
__int64 j;
for (j=it;j<=min(n,last);j++)
sb.insert(ren[j]);
last=it-1;
if (sb.empty())continue;
else
{
multiset<node> ::iterator it=sb.lower_bound(mm[i]);
if (it==sb.end()) continue;
else
{
ans= ans+ (mm[i].x)*500+(mm[i].y)*2;
cun++;
sb.erase(it);
}
}
}
printf("%I64d %I64d\n",cun,ans);
}
return 0;
}