题解:P11349 [NOISG2024 Finals] Problem Setter
题目大意
有
解题思路
该题本质上就是一道贪心题,对于每一道题目,我们在该题可以提交的所有比赛中(即题目质量满足比赛要求),选择满意度最大的比赛,如果该满意度大于该题上交时损失的满意度(即可以使总满意度变大),则将该题交到该比赛上。
如果直接暴力查找匹配每道题,不用想都知道会超时到怀疑人生。那我们就可以采取带预处理的方法,怎么做呢?
我们可以将所有比赛按题目质量要求从小到大排序,这样在后面查找每道题可以提交的最高质量比赛时,便可以利用有序性,用二分法进行查找把复杂度降到
参考代码
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 2e5 + 10;
struct game{ ll m,s; }ga[N];
struct question{ ll q,d; }qu[N];
bool cmp(game &a, game &b){
return a.m < b.m;
}
ll M[N];
int main(){
ll c, p,res = 0;
cin >> c >> p;
for(int i=1;i<=c;i++) cin >> ga[i].m >> ga[i].s;
for(int i=1;i<=p;i++) cin >> qu[i].q >> qu[i].d;
sort(ga+1,ga+c+1,cmp); //排序
for(int i=1;i<=c;i++) M[i] = max(M[i-1],ga[i].s); //预处理
for(int i=1;i<=p;i++){
ll L = 1, R = c;
ll ind = 0; //ind记录该题目能交到的最高质量要求的比赛
while(L <= R){ //二分
ll mid = (L+R)/2;
if(ga[mid].m <= qu[i].q) ind = mid,L = mid + 1;
else R = mid - 1;
}
if(M[ind] > qu[i].d)res += M[ind]-qu[i].d;//如果这个题目能加大满意度,则加上,否则不交该题目
}
cout << res;
return 0;
}