[HDU4864]Task(贪心)

传送门


题目大意:N个机器和M个任务, 每个任务有两个值花费时间xi和难度yi, 每个机器也有两个值最大工作时间xj和最大工作难度yj, 机器可以胜任某个工作的条件是xi>=xj 并且 yi>=yj,机器胜任一个工作可以拿到xj*500+2*yj的钱,现在问你怎么匹配才能使匹配数最大且钱数最多。
( 1<=N,M<=100000 ,0< xi,xj< 1440,0<=yi,yj<=100)

还是一道很有意思的贪心题。
首先发现x的贡献大,那么机器和任务都按照x从大到小排序,如果相同再按y排序。然后我们可以借用田忌赛马的思想,对于所有xi>=xj的机器,我们从中选yi最小的机器,这样我们就可以使得更多机器来完成后面的任务。


#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
typedef long long ll;
const int maxn=100010;
struct node
{
    int x,y;
}a[maxn],b[maxn]; 
bool cmp(node a,node b){if(a.x!=b.x) return a.x>b.x; else return a.y>b.y;} 
int tmp[maxn];
int main()
{
    int n,m;
    while(scanf("%d%d",&n,&m)!=EOF)
    {

    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+n+1,cmp); 
    sort(b+1,b+m+1,cmp); 
    int cnt=0; ll sum=0;
    memset(tmp,0,sizeof(tmp));
    for(int i=1,j=1;i<=m;i++)
    {
        while(j<=n && a[j].x>=b[i].x)
        {
            tmp[a[j].y]++;
            j++;
        }
        for(int k=b[i].y;k<=100;k++)
        {
            if(tmp[k])
            {
                tmp[k]--;
                cnt++;
                sum+=500*b[i].x+2*b[i].y;
                break;
            }
        }
    }
    printf("%d %I64d\n",cnt,sum);

    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/cabi_zgx/article/details/80041076