HDU4864 Task

题意

Today the company has m tasks to complete. The ith task need xi minutes to complete. Meanwhile, this task has a difficulty level yi. The machine whose level below this task’s level yi cannot complete this task. If the company completes this task, they will get (500xi+2yi) dollars.

The company has n machines. Each machine has a maximum working time and a level. If the time for the task is more than the maximum working time of the machine, the machine can not complete this task. Each machine can only complete a task one day. Each task can only be completed by one machine.

The company hopes to maximize the number of the tasks which they can complete today. If there are multiple solutions, they hopes to make the money maximum.

1 < =N <= 100000,1<=M<=100000
0<xi<1440, 0=<yi<=100

分析

参照knownothing的题解。

将任务已x从大到小排序(x相同时已y从大到小排序)。然后也用相同排序方法排序机器。开始遍历任务,找出所有xi(xi>=xj),从中选择yi最小的一个作为这个任务的运行机器。为什么这么贪心,因为若还存在任务(xk,yk)使得这个机器能被使用,但xj>=xk,所以获得金钱更多,优先选择j;若k不能使用这个机器,那么必定也就不存在其他机器能被使用,除非是新加入的机器,但新加入的必定不能完成任务j,所以完成任务保证了最多。

使用了归并写法,时间复杂度\(O(My_i+N)\)

代码

#include<bits/stdc++.h>
#define rg register
#define il inline
#define co const
template<class T>il T read(){
    rg T data=0,w=1;
    rg char ch=getchar();
    while(!isdigit(ch)){
        if(ch=='-') w=-1;
        ch=getchar();
    }
    while(isdigit(ch))
        data=data*10+ch-'0',ch=getchar();
    return data*w;
}
template<class T>il T read(rg T&x){
    return x=read<T>();
}
typedef long long ll;
using namespace std;

co int N=1e5;
struct node{
    int x,y;
    bool operator<(co node&a)co{
        return x^a.x?x>a.x:y>a.y;
    }
}e[N],f[N];
int c[101];
int main(){
//  freopen(".in","r",stdin);
//  freopen(".out","w",stdout);
    int n,m;
    while(~scanf("%d%d",&n,&m)){
        for(int i=0;i<n;++i)
            read(e[i].x),read(e[i].y);
        for(int i=0;i<m;++i)
            read(f[i].x),read(f[i].y);
        sort(e,e+n);
        sort(f,f+m);
        memset(c,0,sizeof c);
        int num=0;
        ll ans=0;
        for(int i=0,j=0;i<m;++i){
            while(j<n&&e[j].x>=f[i].x)
                ++c[e[j].y],++j;
            for(int k=f[i].y;k<=100;++k) if(c[k]){
                ++num,--c[k];
                ans+=500*f[i].x+2*f[i].y;
                break;
            }
        }
        printf("%d %lld\n",num,ans);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/autoint/p/10397083.html