【关键因素值】 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);
}

浙公网安备 33010602011771号