二分题 D - Salary Changing codeforce

题意:给出n个人(n是奇数),s钱;s为总的可以付工钱的钱;

每一个工人有一个付工钱的区间,只要在这个区间范围内,随便一个数都可以当作给这个工人付了钱;

老板要付给每个工人钱,并且付钱的中位数要尽可能大;

问:最大的中位数是多少;

思路:贪心+思维+二分;

我们以中位数为主体进行二分。那么就需要n/2+1个大于等于中位数的数;

这个时候我们先给钱排序,按第一个数从大到小排;

然后check部分,从1到n遍历,如果满足x在区间范围内,就取x这个数;

那么,为什么就要取这个数呢,因为我们迟早要凑到n/2+1个数,所以从大到小的排序,可以让我们在使用的钱

最少的情况下,取出这n/2+1个这样的数;  比如有这样两个区间“6 10” ”7 11“  按从大到小排序,我们假如中位数为8;

我们假如“6 10" 取中位数8 ”7 11“ 取左端点7 那么结果为15

如果”7 11“ 取中位数, 另一个取左端点,则结果为14;

所以代码如下

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int maxn=2e5+10;
 5 struct node
 6 {
 7     int l,r;
 8 }a[maxn];
 9 ll n;ll s;
10 bool cmp(node x,node y)
11 {
12     return x.l>y.l;
13 }
14 int check(ll x)
15 {
16     ll sum=0;
17     ll num=n/2+1;
18     for(int i=1;i<=n;i++){
19         //当num==0之后,所需要的大于等于n/2+1已经满足,所以都取
20         //左端点即可;
21         if(x>=a[i].l&&x<=a[i].r&&num>0){
22             sum+=x;
23             num--;
24         }
25         else{
26             sum+=a[i].l;
27             if(a[i].l>=x) num--;
28         }
29     }
30     if(num>0) return 0;
31     else{
32         if(sum>s) return 0;
33         else return 1;
34     }
35 }
36 int main()
37 {
38     int T;
39     scanf("%d",&T);
40     while(T--){
41         scanf("%lld%lld",&n,&s);
42         for(int i=1;i<=n;i++){
43             scanf("%d%d",&a[i].l,&a[i].r);
44         }
45         sort(a+1,a+1+n,cmp);
46         ll l=a[n/2+1].l;ll r=s;
47         ll ans=l;
48         while(l<=r){
49             ll mid=l+r>>1;
50             if(check(mid)){
51                 ans=mid;
52                 l=mid+1;
53             }
54             else r=mid-1;
55         }
56         printf("%lld\n",ans);
57     }
58     return 0;
59 }

原文地址:https://www.cnblogs.com/pangbi/p/12203295.html

时间: 2024-11-14 00:08:40

二分题 D - Salary Changing codeforce的相关文章

【题解整理】二分题

[题解整理]二分题 题目类型: 二分查找: 二分答案. 大致解题思路: 查找注意有序和返回值: 浮点数注意精度: 整数注意返回值,建议另外维护一个变量,用于储存可行解. 题目 分类 传送门 WA点 poj 2785 二分查找 题解 lightoj 1088 二分查找 题解 lightoj 1307 二分查找 题解 longlong poj 2456 整数二分答案 题解 poj 3104 整数二分答案 题解 poj 3258 整数二分答案 题解 poj 3273 整数二分答案 题解 lightoj

木材加工(裸二分题)(附二分算法粗略介绍)

看到旁边的学弟也在做二分,就手贱2分钟打了一道奇(sha)特(bi)二分题. 原题传送门 好吧,做这道题是为了给新手一个教程 首先我们聊聊二分. 二分利用的也是分治思想 不懂分治思想的可以看看我归并做的那道火柴排队. 传送门 首先要了解一下二分的性质(也就是什么题目要用二分来写.) 我们假设一个题目,如果一个数a能够满足题意,并且U=[数值最小值/数值最大值(看题意)~a]中的数就一定能够满足题意. 那么这道题目就能用来二分.. 或者说一道题目的解的解集为U,如0<i<a;题目的范围是0<

Salary Changing CF-1251D(二分)

题意: 有$n$个员工,$s$元钱,现在要给每个员工发工资.每个员工的工资的范围$(l_i,r_i)$,求所有员工的工资中位数的最大值. 思路: 二分答案,$check$的时候判断工资可以大于等于$mid$的员工个数,用最小代价购买之后判断总价钱会不会超出范围. 代码: 1 //#include<bits/stdc++.h> 2 #include <set> 3 #include <map> 4 #include <stack> 5 #include <

多个限制的二分题 poj 矩形分割

openoj 矩形分割 总时间限制:  1000ms  内存限制: 65536kB 描述 平面上有一个大矩形,其左下角坐标(0,0),右上角坐标(R,R).大矩形内部包含一些小矩形,小矩形都平行于坐标轴且互不重叠.所有矩形的顶点都是整点.要求画一根平行于y轴的直线x=k(k是整数) ,使得这些小矩形落在直线左边的面积必须大于等于落在右边的面积,且两边面积之差最小.并且,要使得大矩形在直线左边的的面积尽可能大.注意:若直线穿过一个小矩形,将会把它切成两个部分,分属左右两侧. 输入 第一行是整数R,

WQS二分题集

WQS二分,一种优化一类特殊DP的方法. 很多最优化问题都是形如“一堆物品,取与不取之间有限制.现在规定只取k个,最大/小化总收益”. 这类问题最自然的想法是:设f[i][j]表示前i个取j个的最大收益,转移即可.复杂度O(n^2). 那么,如果在某些情况下,可以通过将问题稍作转化,变成一个不强制选k个的DP,而最后DP出来的最优解一定正好选了k个,那么问题就会简化很多. WQS二分就是基于这个思想. 首先考虑建一个二维坐标系,x轴是选的数的个数,y轴是最大收益,如果这个x-y图像有凸性,那么就

D. Salary Changing(找中位数)

题:https://codeforces.com/contest/1251/problem/D 题意:给你n个单位需要满足达到的区间,再给个s,s是要分配给n的单位的量,当然∑l<=s,问经过分配后能够达到的最大中位数是多少 题解:二分找中位数,成立原因:代码注释 #include<bits/stdc++.h> using namespace std; typedef long long ll; #define fo(i,a,b) for(int i=a;i<=b;i++) #de

Educational Codeforces Round 75 (Rated for Div. 2) D. Salary Changing

链接: https://codeforces.com/contest/1251/problem/D 题意: You are the head of a large enterprise. n people work at you, and n is odd (i.?e. n is not divisible by 2). You have to distribute salaries to your employees. Initially, you have s dollars for it,

Cable master(二分题 注意精度)

Cable master Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 26596   Accepted: 5673 Description Inhabitants of the Wonderland have decided to hold a regional programming contest. The Judging Committee has volunteered and has promised to

二分题

1.leetcode.4 Median of Two Sorted Arrays 找两个有序数列的中位数.要求log(m+n). ------------------------------------------------------------------ 二分,从b中找a.middle,计算小于等于a.middle的数的个数left. double findMedianSortedArrays(vector<int>& a, vector<int>& b)