浅析拯救小矮人的 nlogn 算法及其证明



题型简介:

有 $ n $ 个人,第 $ i $ 个人身高 $ a_i $ 手长 $ b_i $ ,他们为了从一个高为 $ H $ 的洞中出去,决定搭人梯。如果一个人和他下面的人的身高之和加上他的手长可以达到洞的高度,那么他就可以出去。求最多有多少人能出去。 $ n\leq 10^6 $



算法流程

本题需要贪心,所以我们可以贪心到底。首先我们将所有人,按照他们的最低逃生高度 $ H-a_i-b_i $ 从高到低排序。一个必须要知道的结论:最低逃生高度越高的人,一定越先走

首先我们将所有人按照 $ H-a_i-b_i $ (最低逃生高度)从高到低排序,根据结论越高的人越先走。然后如果是 $ n^2 $ 背包,就是对每个人做有条件的背包,模拟每个人是否能走。

而 $ n\times logn $ 的方法则是记录一个后缀 $ s[] $ ,其中 $ s[i] $ 表示第 $ i $ 个人后面最低逃生高度比他低的所有人的身高总和,然后用一个 $ tot $ 记录前面没有出去的人的身高总和,对于从高到低枚举的第 $ i $ 个人,如果 $ s[i]+tot>=H-a_i-b_i $ 就说明他能出去(于是默认他出去);否则就将这个人的身高和前面所有已经出去的人的身高作比较,如果当前这个人最高那么他就不出去了,不然就从前面已经出去的人里面找到那个最高的人,把他拉回洞里垫在下面,让当前这个人出去!照着这个过程做我们就能得到最优解。


算法证明:

其实这个算法只有两个待考究的地方,问题一:为什么最低逃生高度高的人,一定越先走?这个问题在很多题解里已经讨论过了,难以讲清,本题不做多讲,就用一张图感性一下:

本算法第二个问题在于这句话: 否则就将这个人的身高和前面所有已经出去的人的身高作比较,如果当前这个人最高那么他就不出去了,垫到下面去;不然就从前面已经出去的人里面找到那个最高的人,把他拉回洞里垫在下面,让当前这个人出去!为什么把上面最高的那个人拉下来,这个人就一定可以出去了?为什么只取一个人下来,我们可不可以拉多个人下来,让当前这个人出去的同时为后面的人垫高度?这个我们用两张图解读:



$ code: $

#include<iostream>
#include<cstdio>
#include<iomanip>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<ctime>
#include<cmath>
#include<vector>
#include<queue>
#include<map>
#include<set>#define ll long long
#define db double
#define rg register intusing namespace std;int n,H; //人数;陷阱高度
int tot,ans; //之前没能逃生的人的身高总和;答案
int s[200005]; // s[i]表示在第i个人后面逃生的所有人的身高总和,就是后缀和
priority_queue<int> q; //用来求之前已经逃生的人中,身高最高的人struct su{int a,b,h,id; //身高,手长,最低逃生高度,编号inline bool operator <(const su &i)const{return h>i.h; //按最低逃生高度,从高到底排序 } //(其实说白了就是逃生能力排序,为了方便理解就详细一点)
}p[200005]; //存小矮人信息的数组 peopleinline int qr(){ //快读register char ch; register bool sign=0; rg res=0;while(!isdigit(ch=getchar()))if(ch=='-')sign=1;while(isdigit(ch))res=res*10+(ch^48),ch=getchar();if(sign)return -res; else return res;
}int main(){n=qr();for(rg i=1;i<=n;++i)p[i].a=qr(),p[i].b=qr();H=qr();for(rg i=1;i<=n;++i){p[i].h=H-p[i].a-p[i].b; //最低逃生高度p[i].id=i; //每个人的编号}sort(p+1,p+n+1);for(rg i=n;i>=1;--i)s[i]=s[i+1]+p[i+1].a; //s[i]表示在第i个人后面逃生的所有人堆起来达到的高度for(rg i=1;i<=n;++i){if(tot+s[i]>=p[i].h) q.push(p[i].a), ++ans;//如果在他前面不能逃生的人加上在他后面的人堆起来达到了他的最低逃生高度,就让他走else{if(!q.empty()&&q.top()>p[i].a){ //拿出之前最大的身高和他对比,较大的走tot+=q.top();q.pop(); --ans;q.push(p[i].a); ++ans; //其实ans根本没变,为了高度还原就这样了} else tot+=p[i].a; //否则这个就垫到下面去}}printf("%d\n",ans);return 0;
}

转载于:https://www.cnblogs.com/812-xiao-wen/p/11545341.html

浅析拯救小矮人的 nlogn 算法及其证明相关推荐

  1. [TJOI2013]拯救小矮人(反悔贪心证明),「ICPC World Finals 2019」Hobson 的火车(基环树,差分)

    2021-09-07 test [TJOI2013]拯救小矮人 「ICPC World Finals 2019」Hobson 的火车 [TJOI2013]拯救小矮人 luogu4823 考试题目的数据 ...

  2. 洛谷 P4823 [TJOI2013]拯救小矮人

    题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口. 对于每一个小矮人,我们知道他从 ...

  3. 【bzoj3174】[Tjoi2013]拯救小矮人 贪心+dp

    题目描述 一群小矮人掉进了一个很深的陷阱里,由于太矮爬不上来,于是他们决定搭一个人梯.即:一个小矮人站在另一小矮人的 肩膀上,知道最顶端的小矮人伸直胳膊可以碰到陷阱口.对于每一个小矮人,我们知道他从脚 ...

  4. 【BZOJ3174】【codevs25442075】拯救小矮人,DP+贪心

    Time:2016.07.19 Author:xiaoyimi 转载注明出处谢谢 传送门1 传送门2 传送门3 思路: 比较神的DP "贪心确定DP的状态"--reflash 写了 ...

  5. 使用canvas实现小矮人行走案例

    html代码 <canvas width="500" height="500"></canvas> <script src=&qu ...

  6. 项目管理小故事之小矮人的故事

    小矮人的故事 在古希腊时期的塞浦路斯,曾经有一座城堡里关着一群小矮人.传说他们是因为受到了可怕咒语的诅咒,而被关到这个与世隔绝的地方.他们找不到任何人可以求助,没有粮食,没有水,七个小矮人越来越绝 望 ...

  7. 《讲个故事》七个小矮人 与 七层模型

    某天深夜,标准委员会的工程师们的在酒吧里喝酒划拳,酒过三巡,越玩越嗨,谈到迪士尼电影的时候,他们把电影里7个小矮人的名字写在餐巾纸上,有个人开玩笑说 7 对于网络分层是个好数字.第二天上午在标准化委员 ...

  8. 《讲个故事》七个小矮人与OSI七层模型

    某天深夜,标准委员会的工程师们的在酒吧里喝酒划拳,酒过三巡,越玩越嗨,谈到迪士尼电影的时候,他们把电影里7个小矮人的名字写在餐巾纸上,有个人开玩笑说 7 对于网络分层是个好数字.第二天上午在标准化委员 ...

  9. [codevs 1302] 小矮人(2002年CEOI中欧信息学奥赛)

    描述 矮人们平时有走亲访友的习惯.一天,矮人国要修一条高速公路,矮人们希望他们走亲访友的时候,能够不必穿越高速公路,这样会更安全一些.现在有M个高速公路的修建方案,请你判断这M条高速功能是否能满足矮人 ...

最新文章

  1. Java SE 6之GUI:让界面更加绚丽(上)
  2. 师范类专业物理和计算机选哪个,师范专业太多,哪些师范专业含金量高?资深教师:选这4个就对了...
  3. 双11怎么那么强!之二:浅析淘宝网络通信库tbnet的实现
  4. boost::hana::length用法的测试程序
  5. java jar中jar_java – jar中的jar
  6. liferay 调用ajax
  7. Postman status: 415_415亩!白云首宗农村土地规模化流转成功签约
  8. H3C 路由器的IPSEC ××× 配置
  9. 黑马程序员————java线程之间的通信
  10. 深入理解ES6之——迭代器与生成器
  11. 浙江省二级java考试_2020年浙江省高校计算机二级Java考试大纲
  12. 计算机会计处理流程,会计电算化账务系统期末处理流程
  13. Java+Selenium实现网页截图
  14. 记录一次网线水晶头的安装
  15. 定义与声明、头文件与extern总结
  16. 看这个就够了,谷歌翻译Google 退出中国后如何恢复网页翻译?
  17. 用LSTM做文本情感分类(以英文为例)附github代码
  18. TOTP动态密码认证功能,让天下无贼!
  19. Android 仿美拍,秒拍 ,视频封面选择.有图有真相.
  20. stopstart按钮怎么用_汽车Start-Stop启停技术简明讲解

热门文章

  1. Uncaught TypeError: Cannot read property 'length' of null错误怎么处理?
  2. JAVA作业——JAVA课程的总结及学习计划
  3. datazen Active Directory AD 配置
  4. [C++]有关深复制与copy constructor的一些问题与实例
  5. Configuration、SessionFactory、Session
  6. c#扩展方法奇思妙用高级篇四:对扩展进行分组管理
  7. [pytorch、学习] - 5.6 深度卷积神经网络(AlexNet)
  8. javascript --- [FormData的使用] 文件上传进度条展示 文件上传图片即使预览
  9. react --- render持续调用解决方案
  10. 青海省多地日降水量突破历史极值