题意:
有$n$个员工,$s$元钱,现在要给每个员工发工资。每个员工的工资的范围$(l_i,r_i)$,求所有员工的工资中位数的最大值。
思路:
二分答案,$check$的时候判断工资可以大于等于$mid$的员工个数,用最小代价购买之后判断总价钱会不会超出范围。
代码:
1 //#include<bits/stdc++.h> 2 #include <set> 3 #include <map> 4 #include <stack> 5 #include <cmath> 6 #include <queue> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstring> 11 #include <iostream> 12 #include <algorithm> 13 14 #define ll long long 15 #define pll pair<ll,ll> 16 #define pii pair<int,int> 17 #define bug printf("*********\n") 18 #define FIN freopen("input.txt","r",stdin); 19 #define FON freopen("output.txt","w+",stdout); 20 #define IO ios::sync_with_stdio(false),cin.tie(0) 21 #define ls root<<1 22 #define rs root<<1|1 23 #define pb push_back 24 25 using namespace std; 26 const int inf = 2e9 + 7; 27 const ll Inf = 1e18 + 7; 28 const int maxn = 2e5 + 5; 29 const int mod = 1e9 + 7; 30 31 struct node 32 { 33 ll l, r; 34 }p[maxn]; 35 36 ll s, n; 37 38 bool cmp(const node& a, const node& b) 39 { 40 return a.l < b.l; 41 } 42 43 bool check(ll x) 44 { 45 ll res = 0, m = (n + 1) >> 1; 46 for (int i = n; i >= 1; --i) 47 { 48 if (m && p[i].l <= x && p[i].r >= x) 49 { 50 res += x; 51 m--; 52 } 53 else 54 { 55 res += p[i].l; 56 if (p[i].l >= x && m) m--; 57 } 58 } 59 if (m || res > s) return 0; 60 return 1; 61 } 62 63 64 int main() 65 { 66 int T; 67 scanf("%d", &T); 68 while (T--) 69 { 70 scanf("%lld %lld", &n, &s); 71 for (int i = 1; i <= n; ++i) 72 { 73 scanf("%lld %lld", &p[i].l, &p[i].r); 74 } 75 sort(p + 1, p + 1 + n, cmp); 76 ll l = 0, r = s; 77 while (l <= r) 78 { 79 ll mid = (l + r) >> 1; 80 if (check(mid)) l = mid + 1; 81 else r = mid - 1; 82 } 83 printf("%lld\n", l - 1); 84 } 85 }
原文地址:https://www.cnblogs.com/zhang-Kelly/p/12693339.html
时间: 2024-11-14 00:08:38