(点击此处查看原题)

题意分析

  一共有s元钱,要用这些钱给n个人发工资,发给每个人的工资si有最少和最多限制 si ∈[li,ri],在发给n个人的总工资小于s的情况下,要求发给n个人中的工资的中位数最大,并求出这个最大的中位数(数据满足:∑li <= s )

解题思路

首先注意到发给n个人的工资的中位数mid和n个人所得总工资∑si 具有线性相关性,即 ∑si ∝ mid ,所以我们可以通过二分mid 求出求出满足条件的最优解

随后我们需要判断当前所得的中位数mid是否满足条件 ,显然,只要给至少n/2 + 1个人发的工资si >= mid ,并且∑si <= s ,则此mid满足条件

那么为了满足条件,我们会想着让更多的人发放的工资大于等于mid,同时∑si <= s,为此,我们这样设计判断函数check:

(1)预处理:因为每个人的工资至少有l[i] ,那么我们先为每个人分配最低工资l[i],求得余下总工资 s = s - ∑l[i]

(2)预处理:将n个人的工资按最低工资升序排序

(3)使用的变量:

  cnt:记录发放工资大于等于mid的总人数

  sum:记录剩余的用于发放的钱

(4)处理方法:对于当前发放工资的中位数mid,从最低工资大的人开始向最低工资小的人枚举

  1、若l[i] >= mid

    显然,给这个人发放l[i]的工资即可,cnt++

  2、若l[i] < mid <= r[i] && sum >= mid - l[i]

    cnt++,sum -= mid - l[i],表示将这个人的工资设置为mid,同时减去多给这个人的工资mid-l[i]

    此时会有个疑惑,即为什么发给这个人的不是最低工资?这是一种贪心的思想,因为我们将n个人按最低工资升序排序,同时反向枚举n个人,这样保证了先枚举到的人的mid-l[i]更小,也就是说,我们用最少的代价使得更多的人的工资大于等于mid,这样一来,最后只需要判断cnt 是否大于等于 n/2 + 1 即可

代码区

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<queue>
#include<string>
#include<fstream>
#include<vector>
#include<stack>
#include <map>
#include <iomanip> #define bug cout << "**********" << endl
#define show(x, y) cout<<"["<<x<<","<<y<<"] "
#define LOCAL = 1;
using namespace std;
typedef long long ll;
const ll inf = 1e18 + ;
const int Max = 4e5 + ; struct Salary
{
int l,r;
bool operator<(const Salary& s) const
{
return this->l < s.l;
}
}salary[Max]; int n;
ll s; bool check(ll mid)
{
int cnt = ;
ll sum = s;
for(int i = n ;i >= ; i --)
{
if(salary[i].l >= mid)
{
cnt++;
}
else if(salary[i].r >= mid && sum >= mid - salary[i].l)
// 为了让更多的人的工资大于mid,因此从最低工资大的人开始向前枚举,这样造成的额外工资最小,
// 即总发放的工资最小
{
cnt++;
sum -= mid - salary[i].l;
}
}
return cnt >= n/ + ;
} int main()
{
#ifdef LOCAL
// freopen("input.txt", "r", stdin);
// freopen("output.txt", "w", stdout);
#endif
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d%lld",&n,&s);
for(int i = ;i<= n ;i ++)
{
scanf("%d%d",&salary[i].l,&salary[i].r);
s -= salary[i].l; //保证必定取下界
}
sort(salary+,salary++n);
ll l = salary[n/+].l,r = inf;
while(l <= r)
{
ll mid = (l + r)>>;
if(check(mid))
l = mid +;
else
r = mid -;
}
printf("%lld\n",r);
}
return ;
}

codeforces 1251D Salary Changing (二分+贪心)的更多相关文章

  1. Codeforces 1251D Salary Changing

    D. Salary Changing 大意: 有n个变量, 每个变量有一个取值区间, 要求给这n个变量赋值, 使得n个变量的和不超过S且中位数尽量大(n一定为奇数) 二分答案, 中位数大于等于mid就 ...

  2. codeforces 803D Magazine Ad(二分+贪心)

    Magazine Ad 题目链接:http://codeforces.com/contest/803/problem/D ——每天在线,欢迎留言谈论. 题目大意: 给你一个数字k,和一行字符 例: g ...

  3. Codeforces 1132D - Stressful Training - [二分+贪心+优先队列]

    题目链接:https://codeforces.com/contest/1132/problem/D 题意: 有 $n$ 个学生,他们的电脑有初始电量 $a[1 \sim n]$,他们的电脑每分钟会耗 ...

  4. CodeForces - 343C Read Time (二分+贪心)

    题意:有N个指针头,M个标记,用这N个针头扫描所有的标记,针头之间互不影响,求扫描完M个标记的最短时间 分析:二分搜答案,mid为时间限制,则只要所有的点在mid秒内被扫描到即可. 对于每个指针,若其 ...

  5. codeforces D Salary Changing

    题意:给你n个人,和s块钱,每个人都有一个工资区间,你给所有人都发工资.然后要他们工资的中位数最大. 思路:二分找那个值.那个值要满足至少有n/2+1个工资区间内. #include<cstdi ...

  6. Codeforces Gym 100231B Intervals 线段树+二分+贪心

    Intervals 题目连接: http://codeforces.com/gym/100231/attachments Description 给你n个区间,告诉你每个区间内都有ci个数 然后你需要 ...

  7. 2016-2017 ACM-ICPC CHINA-Final Ice Cream Tower 二分+贪心

    /** 题目:2016-2017 ACM-ICPC CHINA-Final Ice Cream Tower 链接:http://codeforces.com/gym/101194 题意:给n个木块,堆 ...

  8. 【bzoj2097】[Usaco2010 Dec]Exercise 奶牛健美操 二分+贪心

    题目描述 Farmer John为了保持奶牛们的健康,让可怜的奶牛们不停在牧场之间 的小路上奔跑.这些奶牛的路径集合可以被表示成一个点集和一些连接 两个顶点的双向路,使得每对点之间恰好有一条简单路径. ...

  9. codeforces Gym 100338E Numbers (贪心,实现)

    题目:http://codeforces.com/gym/100338/attachments 贪心,每次枚举10的i次幂,除k后取余数r在用k-r补在10的幂上作为候选答案. #include< ...

随机推荐

  1. oc Learning Blog

    http://www.cnblogs.com/heyonggang/p/3351269.html M了个J :http://www.cnblogs.com/mjios/tag/objective-c/ ...

  2. 爬虫之解析库Xpath

    简介 XPath即为XML路径语言(XML Path Language),它是一种用来确定XML文档中某部分位置的语言. XPath基于XML的树状结构,提供在数据结构树中找寻节点的能力.起初XPat ...

  3. jquer绑定和获取属性

    最近每天都在熬夜,今天感觉眼睛特别涩,我决定,今天早睡,哈哈哈,上次总结了jquery控制节点,今天总结jquery控制属性,学习完基础知识,看看下面的案例练习一下,掌握的会更好   属性绑定和获取 ...

  4. 如何确定哪个SMB客户端/会话在Server 2008R2 Windows文件服务器上打开了特定文件?

    参考: http://www.kbase101.com/question/54969.html NetworkOpenedFiles v1.25  https://www.nirsoft.net/ut ...

  5. Git 中无法忽略 .xcuserstate 的解决方法

    1.查看代码变化git status 2.接着输入 git rm –cached 刚才复制的地址 ,如下.git rm --cached RxSwift/Rx.xcodeproj/xcuserdata ...

  6. PYTHON -----pyinstaller的安装

    这几天一直在安装pyinstaller库,发现了一个好方法 因为一直使用pip安装,我只能介绍一下pip安装pyinstaller的方法的注意事项 1:一般pip会在安装python的Scripts文 ...

  7. mongoose 建立schema 和model

    在node中使用MongoDB很多情况下,都是使用mongoose的,所以这集来介绍一下 安装 yarn add mongoose 连接 const mongoose = require(" ...

  8. JMeter-正则表达式(取出银行卡号后4位)

    { : "custName":"奚红艳", : "banks": : [ : : { : : : "id":" ...

  9. CameraLink标准学习

     CameraLink标准学习

  10. hadoop1.2.1安装配置

    原文地址 环境:ubuntu13 使用的用户为普通用户.如:用户ru jdk安装略 1.安装ssh (1) sudo apt-get install openssh-server (2)配置ssh面密 ...