【关键因素值】 task

传送门

题意

\(m\)个任务,第\(i\)个任务有等级\(y_{i}\)和完成所需要的时间\(x_{i}\),利润为\(500 · x_{i} + 2 · y_{i}\)
\(n\)台机器,第\(i\)台机器有等级\(X_{i}\)和最长工作时间\(Y_{i}\),每台机器只能完成一项任务,每个任务只能由一台机器完成
如果任务需要的时间超过机器的时间将不能完成此任务,如果任务的等级超过机器的等级也不能完成此任务
求一个可行的分配方案使得完成的任务数量最多,如果最多的数量相同求最大的利润

数据范围

\(\begin{array}{l}1 \leq N, M \leq 100000 \\ 0<x_{i}<1440 \\ 0 \leq y_{i} \leq 100\end{array}\)

题解

其中任务等级最大是\(100\),所以\(y\)增加1 最多改变利润最多增加\(200\),而\(x\)增加\(1\)就会改变\(500\),所以对于利润优先考虑\(x\)即可
现将所有的任务和机器按照\(x\)排序,然后依次考虑每个任务,在机器还有剩余的情况下将所有\(x\)最大的且能完成当前任务的放入,然后二分找时间满足当前任务的最小的机器

Code

#include<bits/stdc++.h>
using namespace std;
#define rep(i,a,n) for(int i=a;i<n;i++)
#define per(i,a,n) for(int i=n-1;i>=a;i--)
#define fi first 
#define se second 
#define ll long long
typedef pair<int,int> pii;
const int N=1e5+10;
int n,m;
pii ma[N],task[N];
int main(){
    scanf("%d%d",&n,&m);
    rep(i,0,n) scanf("%d%d",&ma[i].fi,&ma[i].se);
    rep(i,0,m) scanf("%d%d",&task[i].fi,&task[i].se);
    sort(ma,ma+n);sort(task,task+m);
    multiset<int>s;
    ll cnt=0,value=0;
    m--,n--;
    for(int i=m,j=n;i>=0;i--){
        while(j>=0 && ma[j].fi >= task[i].fi)
            s.insert(ma[j--].se);
        auto item=s.lower_bound(task[i].se);
        if(item!=s.end()){
            cnt++;
            s.erase(item);
            value+=500*task[i].fi+2*task[i].se;
        }
    }
    printf("%lld %lld\n",cnt,value);
}

posted @ 2020-06-29 21:34  Hyx'  阅读(137)  评论(0)    收藏  举报