http://codeforces.com/gym/101806/problem/T

题目

In the year 2117, Professor Jaemin Yu developed a linear-time algorithm for TSP(Traveling Salesperson Problem). Not long after that happened, all computer systems were destroyed, and nuclear weapons demolished all the lands. You, a great computer expert, also lost your job. With a great despair, you lost your meaning of life long ago. All those things that made your heart beat – where had they gone? After questioning yourself again and again, your conclusion is ...

"If I go to KAIST where I started my first ICPC, can I find a meaning of my life?"

All transportations were destroyed, but you were an avid ICPC participant, and you collected a lot of century-old balloons in Korean Regionals. If you could float a house with some of those balloons...

Currently you have N balloons, and you are trying to float the house into the sky by attaching balloons on the rooftop. Every balloon have altitude limit Li and capacity Di, which indicates you can blow balloons in altitude at most Li, and the balloon busts after increasing the altitude by Di.

Your journey starts at altitude 0. If you have more than 1 balloons enlarged, then the house will ascend too fast. Thus, you will blow one balloon and attach it at the rooftop, increase the altitude until the balloons bust, blow the other balloon and attach it to increase the altitude... to make your house float. For convenience, you may assume that balloons can only increase the altitude.

You don't care about your final altitude, but a balloon can move a fixed amount of distance. Thus, you want to bust as many balloons as possible. You want to calculate a maximum number of balloons you can bust, and check if you can make a journey to KAIST. Let's see whether your 100-year-old ICPC experience can help on this problem!

Input

The first line contains N, the number of balloons. (1 ≤ N ≤ 250, 000)

In next N lines, the altitude limit of i-th balloon Li, and capacity of i-th balloon Di are given as two space-separated integers. (0 ≤ Li ≤ 1015, 1 ≤ Di ≤ 109)

Output

Print the maximum number of balloons you can bust.

题解

类似于UVA 1153

但是发现个问题,按照$L_i$从小到大排序后再用堆将当前任务与之前的任务交换的做法会WA

而按照$L_i+D_i$从小到大排序后再用堆将当前任务与之前的任务交换的做法会AC

按照顺序考虑选气球的问题,将考虑第$a_i$个气球(按照某个顺序选某个特定的气球)设为第$i$个阶段,解为选择的气球数,第1个阶段很容易得到最大的解是什么

数学归纳法,假设之前考虑的阶段都已经达到最大的解了,现在考虑这一阶段(这个气球是否选)

  1. 这一阶段的解肯定小于等于“上一阶段的答案+1”,因为如果大于“上一阶段的答案+1”,那么

    • 如果这个答案包含这一阶段的气球,那么可以丢掉这个气球作为之前那个阶段的解,与假设矛盾
    • 如果这个答案不包含这一阶段的气球,那么可以直接作为之前那个阶段的解,与假设矛盾
  2. 这一阶段的最大的解肯定大于等于“上一阶段的答案”,因为可以直接把上一阶段的答案拿过来用

因此每一个阶段只需要考虑答案是+1还是维持不变(注意,只考虑了数量没有考虑选什么,选的顺序)

也就是,在之前是最优解的情况下

  1. 如果能增加气球,那么可以保证不会丢最优解
  2. 保持气球不变并不能保证不会丢(现在的)最优解

因此我们必须保证不能增加气球的时候才不增加气球= =(这不是废话吗……)

每一阶段都是考虑的气球的数量,而不是哪一个气球,因此要在丢掉某些气球、选另外一些气球、改变顺序仍然无法增加气球数量时才保持不变

为了简化,我们按照顺序考虑每一个气球

考虑丢掉某些气球,选另外一些气球:

  • 让另外的气球里包含当前考虑的气球(增加),剩余的气球都在前面考虑了(丢掉+选变成替换……)

考虑改变顺序

  • 让选气球的顺序就是最好的顺序,不用管改变顺序

因此问题就变成了确定选气球的顺序

假设是$a+b$和$c+d$

肯定能至少选一个,如果$b\leqslant c$,不交换顺序能完成两个,如果$d\leqslant a$,交换顺序能完成两个

变下形,$b+d\leqslant c+d$,$b+d\leqslant a+b$,得到$c+d$大时不交换,$a+b$大时交换

我太弱智了,写了一大坨结果还是不会,本来是想练手写堆的

AC代码

#include<cstdio>
#include<cstdlib>
#include<cctype>
#include<cstring>
#include<algorithm>
#include<set>
#include<cassert>
#define REP(r,x,y) for(register int r=(x); r<(y); r++)
#define REPE(r,x,y) for(register int r=(x); r<=(y); r++)
#define PERE(r,x,y) for(register int r=(x); r>=(y); r--)
#ifdef sahdsg
#define DBG(...) printf(__VA_ARGS__),fflush(stdout)
#else
#define DBG(...) (void)0
#endif
using namespace std;
typedef long long LL;
typedef unsigned long long ULL; char ch; int si;
char buf[1<<21],*p1=buf,*p2=buf;
int beof = 0;
#define gc() (beof?EOF:(p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(beof=EOF):*p1++))
#define gl(x) {char*s=x;while(isspace(*s=gc()));s++;while(!isspace(*s=gc()))s++;*s=0;} template<class T>
inline void read(T &x) {
x=0; si=1; for(ch=gc();!isdigit(ch) && ch!='-';ch=gc()) if(beof) return;
if(ch=='-'){si=-1,ch=gc();} for(;isdigit(ch);ch=gc())x=x*10+ch-'0';
x*=si;
}
//template<class T, class...A> inline void read(T &x, A&...a){read(x); read(a...);} #define MAXN 250007
struct node {
LL l, d;
} hp[MAXN];
inline bool cmp(const node& l, const node& r) {
return l.l<r.l;
}
namespace _hp {
int sz=0;
inline void down() {
for(int f=2; f<=sz; f<<=1) {
if(f<sz && hp[f].d<hp[f+1].d) f++;
if(hp[f].d>hp[f>>1].d) {
swap(hp[f],hp[f>>1]);
} else {
break;
}
}
}
inline void up() {
for(int f=sz; f>1; f>>=1) {
if(hp[f].d>hp[f>>1].d) {
swap(hp[f],hp[f>>1]);
} else {
break;
}
}
}
inline void hpins(LL l, LL d) {
sz++;
hp[sz].l=l, hp[sz].d=d;
up();
}
inline node& hppop() {
swap(hp[1],hp[sz]);
sz--;
down();
return hp[sz+1];
}
}
using _hp::hpins;
using _hp::hppop;
node arr[MAXN];
int main() {
#ifdef sahdsg
freopen("in.txt", "r", stdin);
#endif
int n; read(n);
REP(i,0,n) {
read(arr[i].l); read(arr[i].d); arr[i].l+=arr[i].d;
}
sort(arr,arr+n,cmp);
LL now=0, ans=0;
REP(i,0,n) {
hpins(arr[i].l, arr[i].d);
now+=arr[i].d;
if(now<=arr[i].l) {
ans++;
} else {
LL d=hppop().d;
now-=d;
}
}
printf("%lld\n", ans);
return 0;
}

Gym 101806T Touch The Sky的更多相关文章

  1. Gym - 101806T: Touch The Sky(贪心)

    Figure: The house floats up in the sky by balloons. This picture is also used in 2018 KAIST RUN Spri ...

  2. scala 学习笔记(06) OOP(下)多重继承 及 AOP

    一.多继承 上篇trait中,已经看到了其用法十分灵活,可以借此实现类似"多重继承"的效果,语法格式为: class/trait A extends B with C with D ...

  3. TED_Topic5:How virtual reality can create the ultimate empathy machine

    By Chris Milk # Background about our speaker Working at the frontiers of interactive technology, Chr ...

  4. ZT I Believe I Can Fly(我相信我能飞)

    I Believe I Can Fly(我相信我能飞) 歌手:R. Kelly(罗 凯利) 歌词部分 I used to think that I could not go on 我原以为我无法坚持下 ...

  5. Codeforces Gym 100531G Grave 水题

    Problem G. Grave 题目连接: http://codeforces.com/gym/100531/attachments Description Gerard develops a Ha ...

  6. Codeforces Gym 100500F Problem F. Door Lock 二分

    Problem F. Door LockTime Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/100500/at ...

  7. Codeforces Gym 100002 C "Cricket Field" 暴力

    "Cricket Field" Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/1000 ...

  8. mkdir,rmdir,cp,rm,mv,cat,touch用法

    一.mkdir新建目录 1.进入tmp目录,查看该目录下面的子目录 [root@localhost ~]# cd /tmp[root@localhost tmp]# lshsperfdata_root ...

  9. UC浏览器中touch事件的异常记录

    以前也在UC上面栽过几个坑,不过都是页面显示方面的.上个周的时候,商品详情页重做,要添加个上拉显示详情的效果. 有两个条件需要判断: 1.是否到达底部: 2.到达底部之后拖动的y轴距离. 效果写完后, ...

随机推荐

  1. MYSQL5.7的安装(yum、二进制、编译安装)

    目录 一.环境说明 二.YUM安装 1.安装MYSQL-YUM源 2.安装说明 3.安装前的准备 4.安装 5.启动 三.变更root密码 四.BINARY-INSTALL 1.基础环境准备 2.建立 ...

  2. MSYQL主从复制-Gtid方式

    目录 1.MYSQL主从复制-Gtid方式 1.环境准备 2.Master配置 3.Slave配置 4.报错&解决 我叫张贺,贪财好色.一名合格的LINUX运维工程师,专注于LINUX的学习和 ...

  3. 201871010133-赵永军《面向对象程序设计(java)》第一周学习总结

    <面向对象程序设计(java)>第一周学习总结 正文开头: 项目 内容 这个作业属于哪个课程 https://www.cnblogs.com/nwnu-daizh/ 这个作业的要求在哪里 ...

  4. redis在centos7下安装(源码编译)

    下载 地址:http://www.redis.cn/download.html 下载稳定版本 把安装包上传到服务器 linux下安装 解压 进入解压后的目录,编译 创建目录,安装并指定目录 修改配置 ...

  5. for循环创建的a标签,当点击时如何确定点击的是哪一个标签?

    创建 代码: js: 效果: 原因: html代码:这种获取选中标签的方式,是通过监听body来实现的,所以body上要增加这个onclick(this)

  6. 【UOJ276】【清华集训2016】汽水(分数规划+点分治)

    点此看题面 大致题意: 给你一棵树,要求你选择一条树上路径,使得这条路径上边权的平均值与定值\(k\)的差的绝对值最小.求出这个最小值. 分数规划 看到平均值,首先就应该想到分数规划吧. 我们二分答案 ...

  7. MS SQL OPENJSON JSON

    前段时间,有写过一个小练习<MS SQL读取JSON数据>https://www.cnblogs.com/insus/p/10911739.html 晚上为一个网友的问题,尝试获取较深层节 ...

  8. iOS:捋一遍View的生命周期

    一.介绍 前面介绍了VC的生命周期,闲着没事也来捋一捋View的生命周期,简单用两个类型的View来监测.一个View纯代码创建,另一个View使用Xib创建. 二 .代码 MyCodeView:  ...

  9. Linux安装最新版Node.js

    由于直接yum安装的nodejs版本太低,所以本篇文章向大家介绍在 Linux 上安装 Node.js 最新版的方法. 安装环境 本机系统:CentOS Linux release 7.5 Node. ...

  10. 一次业务网关用ASP.NET Core 2.1重构的小结

    目录 前言 统一鉴权 服务限流 路由转发 参数重组 链路跟踪 熔断降级 服务计次 业务指标监控 日志记录 迭代更新 总结 前言 对于API网关,业界貌似对它进行下划分,有下面几个分类/场景. 面向We ...